summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-01-13 15:50:02 +0100
committerSergei Golubchik <sergii@pisem.net>2012-01-13 15:50:02 +0100
commit4f435bddfd44d40999f88685c61cc04e319d8d6c (patch)
treef9d0655a0d901b87f918a736741144b502cba3f6
parent8c2bcdf85ff753bceeb5b235f3605e348e6f9e1d (diff)
parent6ca4ca7d37fed3b3da18666768de6a2f8c34bc7b (diff)
downloadmariadb-git-4f435bddfd44d40999f88685c61cc04e319d8d6c.tar.gz
5.3 merge
-rw-r--r--.bzrignore2
-rw-r--r--BUILD/FINISH.sh1
-rwxr-xr-xBUILD/check-cpu15
-rwxr-xr-xBUILD/compile-dist16
-rwxr-xr-xBUILD/compile-pentium-icc-valgrind-max14
-rwxr-xr-xBUILD/compile-pentium-valgrind-max14
-rwxr-xr-xBUILD/compile-pentium64-valgrind-max14
-rwxr-xr-xBUILD/compile-solaris-amd64-forte18
-rwxr-xr-xBUILD/compile-solaris-sparc15
-rwxr-xr-xBUILD/compile-solaris-sparc-forte15
-rw-r--r--CMakeLists.txt3
-rw-r--r--client/my_readline.h2
-rw-r--r--client/mysql.cc23
-rw-r--r--client/mysql_upgrade.c7
-rw-r--r--client/mysqladmin.cc12
-rw-r--r--client/mysqlbinlog.cc8
-rw-r--r--client/mysqlcheck.c8
-rw-r--r--client/mysqldump.c7
-rw-r--r--client/mysqlimport.c17
-rw-r--r--client/mysqlshow.c7
-rw-r--r--client/mysqlslap.c2
-rw-r--r--client/mysqltest.cc97
-rw-r--r--client/readline.cc2
-rw-r--r--client/sql_string.cc.dontuse2
-rw-r--r--client/sql_string.h.dontuse3
-rw-r--r--cmd-line-utils/libedit/README12
-rw-r--r--cmd-line-utils/libedit/chared.c289
-rw-r--r--cmd-line-utils/libedit/chared.h50
-rw-r--r--cmd-line-utils/libedit/chartype.c361
-rw-r--r--cmd-line-utils/libedit/chartype.h252
-rw-r--r--cmd-line-utils/libedit/common.c252
-rw-r--r--cmd-line-utils/libedit/config.h3
-rw-r--r--cmd-line-utils/libedit/el.c232
-rw-r--r--cmd-line-utils/libedit/el.h53
-rw-r--r--cmd-line-utils/libedit/el_terminal.h (renamed from cmd-line-utils/libedit/el_term.h)72
-rw-r--r--cmd-line-utils/libedit/eln.c364
-rw-r--r--cmd-line-utils/libedit/emacs.c161
-rw-r--r--cmd-line-utils/libedit/filecomplete.c237
-rw-r--r--cmd-line-utils/libedit/filecomplete.h6
-rw-r--r--cmd-line-utils/libedit/hist.c77
-rw-r--r--cmd-line-utils/libedit/hist.h29
-rw-r--r--cmd-line-utils/libedit/histedit.h143
-rw-r--r--cmd-line-utils/libedit/history.c488
-rw-r--r--cmd-line-utils/libedit/historyn.c5
-rw-r--r--cmd-line-utils/libedit/keymacro.c (renamed from cmd-line-utils/libedit/key.c)422
-rw-r--r--cmd-line-utils/libedit/keymacro.h (renamed from cmd-line-utils/libedit/key.h)57
-rw-r--r--cmd-line-utils/libedit/makelist.sh25
-rw-r--r--cmd-line-utils/libedit/map.c217
-rw-r--r--cmd-line-utils/libedit/map.h16
-rw-r--r--cmd-line-utils/libedit/np/strlcpy.c1
-rw-r--r--cmd-line-utils/libedit/np/unvis.c451
-rw-r--r--cmd-line-utils/libedit/np/vis.c301
-rw-r--r--cmd-line-utils/libedit/np/vis.h49
-rw-r--r--cmd-line-utils/libedit/np/wcsdup.c43
-rw-r--r--cmd-line-utils/libedit/parse.c124
-rw-r--r--cmd-line-utils/libedit/parse.h10
-rw-r--r--cmd-line-utils/libedit/prompt.c83
-rw-r--r--cmd-line-utils/libedit/prompt.h14
-rw-r--r--cmd-line-utils/libedit/read.c265
-rw-r--r--cmd-line-utils/libedit/read.h4
-rw-r--r--cmd-line-utils/libedit/readline.c719
-rw-r--r--cmd-line-utils/libedit/readline/readline.h28
-rw-r--r--cmd-line-utils/libedit/refresh.c470
-rw-r--r--cmd-line-utils/libedit/refresh.h4
-rw-r--r--cmd-line-utils/libedit/search.c160
-rw-r--r--cmd-line-utils/libedit/search.h14
-rw-r--r--cmd-line-utils/libedit/sig.c86
-rw-r--r--cmd-line-utils/libedit/sig.h10
-rw-r--r--cmd-line-utils/libedit/sys.h64
-rw-r--r--cmd-line-utils/libedit/terminal.c (renamed from cmd-line-utils/libedit/term.c)1047
-rw-r--r--cmd-line-utils/libedit/tokenizer.c111
-rw-r--r--cmd-line-utils/libedit/tokenizern.c5
-rw-r--r--cmd-line-utils/libedit/tty.c138
-rw-r--r--cmd-line-utils/libedit/tty.h7
-rw-r--r--cmd-line-utils/libedit/vi.c358
-rw-r--r--dbug/tests.c2
-rw-r--r--extra/comp_err.c3
-rw-r--r--extra/innochecksum.c2
-rw-r--r--extra/my_print_defaults.c3
-rw-r--r--extra/mysql_waitpid.c3
-rw-r--r--extra/perror.c2
-rw-r--r--extra/replace.c2
-rw-r--r--extra/resolve_stack_dump.c3
-rw-r--r--extra/resolveip.c3
-rw-r--r--extra/yassl/src/crypto_wrapper.cpp2
-rw-r--r--extra/yassl/src/yassl_error.cpp2
-rw-r--r--extra/yassl/src/yassl_imp.cpp2
-rw-r--r--extra/yassl/src/yassl_int.cpp2
-rw-r--r--extra/yassl/taocrypt/include/blowfish.hpp2
-rw-r--r--extra/yassl/taocrypt/include/runtime.hpp2
-rw-r--r--extra/yassl/taocrypt/src/aes.cpp2
-rw-r--r--extra/yassl/taocrypt/src/algebra.cpp2
-rw-r--r--extra/yassl/taocrypt/src/blowfish.cpp2
-rw-r--r--extra/yassl/taocrypt/src/coding.cpp2
-rw-r--r--extra/yassl/taocrypt/src/integer.cpp2
-rw-r--r--extra/yassl/taocrypt/src/misc.cpp2
-rw-r--r--extra/yassl/taocrypt/src/twofish.cpp2
-rw-r--r--extra/yassl/testsuite/test.hpp2
-rw-r--r--include/heap.h3
-rw-r--r--include/m_ctype.h3
-rw-r--r--include/m_string.h12
-rw-r--r--include/maria.h2
-rw-r--r--include/my_alarm.h3
-rw-r--r--include/my_bitmap.h2
-rw-r--r--include/my_dbug.h4
-rw-r--r--include/my_decimal_limits.h2
-rw-r--r--include/my_getopt.h2
-rw-r--r--include/my_global.h33
-rw-r--r--include/my_stacktrace.h3
-rw-r--r--include/my_time.h3
-rw-r--r--include/myisam.h2
-rw-r--r--include/mysql.h3
-rw-r--r--include/mysql.h.pp1
-rw-r--r--include/mysql/client_plugin.h7
-rw-r--r--include/mysql/plugin.h40
-rw-r--r--include/mysql_com.h1
-rw-r--r--include/mysql_embed.h3
-rw-r--r--include/mysys_err.h3
-rw-r--r--include/sslopt-longopts.h3
-rw-r--r--include/welcome_copyright_notice.h8
-rw-r--r--libmysql/CMakeLists.txt2
-rw-r--r--libmysql/get_password.c31
-rw-r--r--libmysql/libmysql.c2
-rw-r--r--libmysqld/CMakeLists.txt2
-rw-r--r--man/mysql-stress-test.pl.12
-rw-r--r--man/mysql-test-run.pl.12
-rw-r--r--man/mysql_client_test.12
-rw-r--r--man/mysqltest.12
-rw-r--r--mysql-test/include/common-tests.inc6
-rw-r--r--mysql-test/include/default_mysqld.cnf2
-rw-r--r--mysql-test/include/gis_keys.inc1
-rw-r--r--mysql-test/include/have_plugin_auth.inc9
-rw-r--r--mysql-test/include/icp_tests.inc108
-rw-r--r--mysql-test/include/index_merge1.inc3
-rw-r--r--mysql-test/include/mix1.inc4
-rw-r--r--mysql-test/include/mtr_check.sql5
-rw-r--r--mysql-test/include/mtr_warnings.sql2
-rw-r--r--mysql-test/lib/My/Config.pm2
-rw-r--r--mysql-test/lib/My/ConfigFactory.pm2
-rw-r--r--mysql-test/lib/My/Options.pm2
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process.cc2
-rw-r--r--mysql-test/lib/My/SafeProcess/safe_process.pl2
-rw-r--r--mysql-test/lib/My/Test.pm3
-rw-r--r--mysql-test/lib/mtr_cases.pm55
-rw-r--r--mysql-test/lib/mtr_gprof.pl2
-rw-r--r--mysql-test/lib/mtr_process.pl4
-rwxr-xr-xmysql-test/mysql-test-run.pl50
-rw-r--r--mysql-test/r/archive.result11
-rw-r--r--mysql-test/r/cast.result9
-rw-r--r--mysql-test/r/compress.result3
-rw-r--r--mysql-test/r/delete.result8
-rw-r--r--mysql-test/r/derived.result10
-rw-r--r--mysql-test/r/derived_view.result49
-rw-r--r--mysql-test/r/distinct.result3
-rw-r--r--mysql-test/r/endspace.result4
-rw-r--r--mysql-test/r/error_simulation.result15
-rw-r--r--mysql-test/r/explain.result20
-rw-r--r--mysql-test/r/foreign_key.result4
-rw-r--r--mysql-test/r/fulltext.result2
-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_group.result18
-rw-r--r--mysql-test/r/func_op.result3
-rw-r--r--mysql-test/r/func_str.result3
-rw-r--r--mysql-test/r/gis.result34
-rw-r--r--mysql-test/r/greedy_optimizer.result155
-rw-r--r--mysql-test/r/group_by.result11
-rw-r--r--mysql-test/r/group_min_max.result253
-rw-r--r--mysql-test/r/index_merge_innodb.result3
-rw-r--r--mysql-test/r/index_merge_myisam.result3
-rw-r--r--mysql-test/r/information_schema.result3
-rw-r--r--mysql-test/r/innodb_icp.result109
-rw-r--r--mysql-test/r/insert_update.result2
-rw-r--r--mysql-test/r/join.result5
-rw-r--r--mysql-test/r/join_cache.result246
-rw-r--r--mysql-test/r/join_nested.result4
-rw-r--r--mysql-test/r/join_nested_jcl6.result10
-rw-r--r--mysql-test/r/join_outer.result4
-rw-r--r--mysql-test/r/join_outer_jcl6.result10
-rw-r--r--mysql-test/r/maria_icp.result109
-rw-r--r--mysql-test/r/maria_mrr.result3
-rw-r--r--mysql-test/r/multi_update.result4
-rw-r--r--mysql-test/r/myisam.result24
-rw-r--r--mysql-test/r/myisam_icp.result116
-rw-r--r--mysql-test/r/myisam_mrr.result4
-rw-r--r--mysql-test/r/mysqld--help-notwin.result4
-rw-r--r--mysql-test/r/named_pipe.result3
-rw-r--r--mysql-test/r/order_by.result3
-rw-r--r--mysql-test/r/partition_innodb_plugin.result23
-rw-r--r--mysql-test/r/pool_of_threads.result6
-rw-r--r--mysql-test/r/ps.result6
-rw-r--r--mysql-test/r/query_cache.result17
-rw-r--r--mysql-test/r/select.result71
-rw-r--r--mysql-test/r/select_jcl6.result77
-rw-r--r--mysql-test/r/select_pkeycache.result71
-rw-r--r--mysql-test/r/shm.result3
-rw-r--r--mysql-test/r/ssl.result3
-rw-r--r--mysql-test/r/ssl_compress.result3
-rw-r--r--mysql-test/r/status.result2
-rw-r--r--mysql-test/r/subselect.result310
-rw-r--r--mysql-test/r/subselect2.result37
-rw-r--r--mysql-test/r/subselect3.result70
-rw-r--r--mysql-test/r/subselect3_jcl6.result74
-rw-r--r--mysql-test/r/subselect4.result182
-rw-r--r--mysql-test/r/subselect_cache.result71
-rw-r--r--mysql-test/r/subselect_extra.result23
-rw-r--r--mysql-test/r/subselect_extra_no_semijoin.result8
-rw-r--r--mysql-test/r/subselect_innodb.result2
-rw-r--r--mysql-test/r/subselect_mat.result275
-rw-r--r--mysql-test/r/subselect_mat_cost.result38
-rw-r--r--mysql-test/r/subselect_mat_cost_bugs.result24
-rw-r--r--mysql-test/r/subselect_no_mat.result299
-rw-r--r--mysql-test/r/subselect_no_opts.result296
-rw-r--r--mysql-test/r/subselect_no_scache.result313
-rw-r--r--mysql-test/r/subselect_no_semijoin.result349
-rw-r--r--mysql-test/r/subselect_partial_match.result80
-rw-r--r--mysql-test/r/subselect_sj.result214
-rw-r--r--mysql-test/r/subselect_sj2.result43
-rw-r--r--mysql-test/r/subselect_sj2_jcl6.result143
-rw-r--r--mysql-test/r/subselect_sj2_mat.result65
-rw-r--r--mysql-test/r/subselect_sj_aria.result59
-rw-r--r--mysql-test/r/subselect_sj_jcl6.result243
-rw-r--r--mysql-test/r/subselect_sj_mat.result337
-rw-r--r--mysql-test/r/subselect_sj_nonmerged.result31
-rw-r--r--mysql-test/r/table_elim.result3
-rw-r--r--mysql-test/r/trigger.result44
-rw-r--r--mysql-test/r/type_datetime.result11
-rw-r--r--mysql-test/r/type_newdecimal.result43
-rw-r--r--mysql-test/r/union.result3
-rw-r--r--mysql-test/r/variables-notembedded.result2
-rw-r--r--mysql-test/r/variables.result2
-rw-r--r--mysql-test/r/view.result3
-rw-r--r--mysql-test/r/view_grant.result224
-rw-r--r--mysql-test/std_data/bug887051.txt2
-rw-r--r--mysql-test/std_data/checkDBI_DBD-mysql.pl2
-rw-r--r--mysql-test/suite/engines/funcs/r/de_calendar_range.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_2_unique_constraints_duplicate_update.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_duplicate_update.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_error.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_pk_constraint_ignore.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_duplicate_update.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_error.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_calendar_unique_constraint_ignore.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_duplicate_update.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_error.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_pk_constraint_ignore.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_duplicate_update.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_error.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_calendar_unique_constraint_ignore.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/in_multicolumn_number_pk_constraint_duplicate_update.result2
-rw-r--r--mysql-test/suite/engines/funcs/r/up_calendar_range.result2
-rw-r--r--mysql-test/suite/engines/funcs/t/de_calendar_range.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_calendar_2_unique_constraints_duplicate_update.test4
-rw-r--r--mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_duplicate_update.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_error.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_ignore.test4
-rw-r--r--mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_duplicate_update.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_error.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_ignore.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_duplicate_update.test4
-rw-r--r--mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_error.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_ignore.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_duplicate_update.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_error.test5
-rw-r--r--mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_ignore.test4
-rw-r--r--mysql-test/suite/engines/funcs/t/in_multicolumn_number_pk_constraint_duplicate_update.test4
-rw-r--r--mysql-test/suite/engines/funcs/t/up_calendar_range.test5
-rw-r--r--mysql-test/suite/federated/combinations8
-rw-r--r--mysql-test/suite/federated/federated.inc1
-rw-r--r--mysql-test/suite/federated/federated_partition.test1
-rw-r--r--mysql-test/suite/federated/federated_server.result2
-rw-r--r--mysql-test/suite/federated/federated_server.test2
-rw-r--r--mysql-test/suite/federated/federated_transactions.test1
-rw-r--r--mysql-test/suite/federated/federatedx.result (renamed from mysql-test/suite/federated/federated.result)0
-rw-r--r--mysql-test/suite/federated/federatedx.test (renamed from mysql-test/suite/federated/federated.test)1
-rw-r--r--mysql-test/suite/federated/have_federated_db.inc6
-rw-r--r--mysql-test/suite/federated/have_federatedx.inc5
-rw-r--r--mysql-test/suite/federated/have_federatedx.opt (renamed from mysql-test/suite/federated/suite.opt)1
-rw-r--r--mysql-test/suite/federated/suite.pm20
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_views.result3
-rw-r--r--mysql-test/suite/funcs_1/r/memory_views.result3
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_views-big.result3
-rw-r--r--mysql-test/suite/funcs_1/t/is_engines_federated.test2
-rw-r--r--mysql-test/suite/funcs_1/views/views_master.inc6
-rw-r--r--mysql-test/suite/innodb/r/innodb-index.result14
-rw-r--r--mysql-test/suite/innodb/r/innodb-lock.result17
-rw-r--r--mysql-test/suite/innodb/r/innodb.result90
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug12661768.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb_bug59641.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb_gis.result2
-rw-r--r--mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result10
-rw-r--r--mysql-test/suite/innodb/r/innodb_mysql.result52
-rw-r--r--mysql-test/suite/innodb/r/innodb_replace.result77
-rw-r--r--mysql-test/suite/innodb/t/innodb-index.test18
-rw-r--r--mysql-test/suite/innodb/t/innodb-lock.test41
-rw-r--r--mysql-test/suite/innodb/t/innodb.test74
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug12661768.test50
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug59641.test4
-rw-r--r--mysql-test/suite/innodb/t/innodb_lock_wait_timeout_1.test8
-rw-r--r--mysql-test/suite/innodb/t/innodb_mysql.test45
-rw-r--r--mysql-test/suite/innodb/t/innodb_replace.test186
-rw-r--r--mysql-test/suite/maria/r/maria-autozerofill.result3
-rw-r--r--mysql-test/suite/maria/r/maria-recovery3.result22
-rw-r--r--mysql-test/suite/maria/t/compat_aliases-master.opt1
-rw-r--r--mysql-test/suite/maria/t/maria-recovery3.test18
-rw-r--r--mysql-test/suite/pbxt/r/derived.result8
-rw-r--r--mysql-test/suite/pbxt/r/distinct.result3
-rw-r--r--mysql-test/suite/pbxt/r/endspace.result15
-rw-r--r--mysql-test/suite/pbxt/r/func_group.result3
-rw-r--r--mysql-test/suite/pbxt/r/func_op.result3
-rw-r--r--mysql-test/suite/pbxt/r/greedy_optimizer.result155
-rw-r--r--mysql-test/suite/pbxt/r/group_by.result3
-rw-r--r--mysql-test/suite/pbxt/r/group_min_max.result2
-rw-r--r--mysql-test/suite/pbxt/r/heap.result.THIS (renamed from mysql-test/suite/pbxt/r/heap.result)0
-rw-r--r--mysql-test/suite/pbxt/r/join.result5
-rw-r--r--mysql-test/suite/pbxt/r/join_nested.result3
-rw-r--r--mysql-test/suite/pbxt/r/join_outer.result3
-rw-r--r--mysql-test/suite/pbxt/r/select.result7
-rw-r--r--mysql-test/suite/pbxt/r/subselect.result45
-rw-r--r--mysql-test/suite/pbxt/r/union.result3
-rw-r--r--mysql-test/suite/pbxt/r/view_grant.result.THIS (renamed from mysql-test/suite/pbxt/r/view_grant.result)0
-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/endspace.test10
-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/greedy_optimizer.test5
-rw-r--r--mysql-test/suite/pbxt/t/group_by.test3
-rw-r--r--mysql-test/suite/pbxt/t/heap.test.THIS (renamed from mysql-test/suite/pbxt/t/heap.test)0
-rw-r--r--mysql-test/suite/pbxt/t/join.test5
-rw-r--r--mysql-test/suite/pbxt/t/join_nested.test6
-rw-r--r--mysql-test/suite/pbxt/t/join_outer.test5
-rw-r--r--mysql-test/suite/pbxt/t/select.test6
-rw-r--r--mysql-test/suite/pbxt/t/subselect.test13
-rw-r--r--mysql-test/suite/pbxt/t/union.test3
-rw-r--r--mysql-test/suite/pbxt/t/view_grant.test.THIS (renamed from mysql-test/suite/pbxt/t/view_grant.test)0
-rw-r--r--mysql-test/suite/percona/innodb_sys_index.result17
-rw-r--r--mysql-test/suite/percona/innodb_sys_index.test21
-rw-r--r--mysql-test/suite/perfschema/r/pfs_upgrade.result180
-rw-r--r--mysql-test/suite/plugins/r/dialog.result26
-rw-r--r--mysql-test/suite/plugins/r/feedback_plugin_install.result (renamed from mysql-test/r/feedback_plugin_install.result)0
-rw-r--r--mysql-test/suite/plugins/r/feedback_plugin_load.result (renamed from mysql-test/r/feedback_plugin_load.result)0
-rw-r--r--mysql-test/suite/plugins/r/feedback_plugin_send.result (renamed from mysql-test/r/feedback_plugin_send.result)0
-rw-r--r--mysql-test/suite/plugins/r/fulltext_plugin.result (renamed from mysql-test/r/fulltext_plugin.result)0
-rw-r--r--mysql-test/suite/plugins/r/pam.result22
-rw-r--r--mysql-test/suite/plugins/suite.pm8
-rw-r--r--mysql-test/suite/plugins/t/dialog.test54
-rw-r--r--mysql-test/suite/plugins/t/feedback_plugin_install.opt (renamed from mysql-test/t/feedback_plugin_install.opt)0
-rw-r--r--mysql-test/suite/plugins/t/feedback_plugin_install.test (renamed from mysql-test/t/feedback_plugin_install.test)0
-rw-r--r--mysql-test/suite/plugins/t/feedback_plugin_load.opt (renamed from mysql-test/t/feedback_plugin_load.opt)0
-rw-r--r--mysql-test/suite/plugins/t/feedback_plugin_load.test (renamed from mysql-test/t/feedback_plugin_load.test)0
-rw-r--r--mysql-test/suite/plugins/t/feedback_plugin_send.test (renamed from mysql-test/t/feedback_plugin_send.test)15
-rw-r--r--mysql-test/suite/plugins/t/fulltext_plugin.test (renamed from mysql-test/t/fulltext_plugin.test)0
-rw-r--r--mysql-test/suite/plugins/t/pam.test46
-rw-r--r--mysql-test/suite/sys_vars/r/aria_recover_basic.result14
-rw-r--r--mysql-test/suite/sys_vars/r/aria_repair_threads_basic.result3
-rw-r--r--mysql-test/suite/sys_vars/r/aria_sort_buffer_size_basic.result3
-rw-r--r--mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result22
-rw-r--r--mysql-test/suite/sys_vars/r/join_cache_level_basic.result12
-rw-r--r--mysql-test/suite/sys_vars/r/optimizer_switch_basic.result16
-rw-r--r--mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown1.result2
-rw-r--r--mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown2.result2
-rw-r--r--mysql-test/suite/sys_vars/r/sql_big_tables_func.result31
-rw-r--r--mysql-test/suite/sys_vars/t/aria_recover_basic.test12
-rw-r--r--mysql-test/suite/sys_vars/t/sql_big_tables_func.test3
-rw-r--r--mysql-test/suite/vcol/inc/vcol_keys.inc2
-rw-r--r--mysql-test/suite/vcol/inc/vcol_select.inc6
-rw-r--r--mysql-test/suite/vcol/inc/vcol_view.inc6
-rw-r--r--mysql-test/suite/vcol/r/vcol_keys_myisam.result2
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_innodb.result3
-rw-r--r--mysql-test/suite/vcol/r/vcol_select_myisam.result3
-rw-r--r--mysql-test/suite/vcol/r/vcol_view_innodb.result3
-rw-r--r--mysql-test/suite/vcol/r/vcol_view_myisam.result3
-rw-r--r--mysql-test/t/archive.test2
-rw-r--r--mysql-test/t/auth_rpl-master.opt3
-rw-r--r--mysql-test/t/auth_rpl-slave.opt4
-rw-r--r--mysql-test/t/cast.test1
-rw-r--r--mysql-test/t/derived.test5
-rw-r--r--mysql-test/t/derived_view.test17
-rw-r--r--mysql-test/t/distinct.test6
-rw-r--r--mysql-test/t/endspace.test2
-rw-r--r--mysql-test/t/error_simulation.test19
-rw-r--r--mysql-test/t/explain.test21
-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.test6
-rw-r--r--mysql-test/t/func_op.test3
-rw-r--r--mysql-test/t/func_str.test6
-rw-r--r--mysql-test/t/gis-precise.test3
-rw-r--r--mysql-test/t/gis.test47
-rw-r--r--mysql-test/t/greedy_optimizer.test5
-rw-r--r--mysql-test/t/group_by.test9
-rw-r--r--mysql-test/t/group_min_max.test43
-rw-r--r--mysql-test/t/index_merge_innodb.test3
-rw-r--r--mysql-test/t/information_schema.test3
-rw-r--r--mysql-test/t/information_schema_all_engines.test9
-rw-r--r--mysql-test/t/join.test4
-rw-r--r--mysql-test/t/join_cache.test181
-rw-r--r--mysql-test/t/join_nested.test14
-rw-r--r--mysql-test/t/join_nested_jcl6.test5
-rw-r--r--mysql-test/t/join_outer.test13
-rw-r--r--mysql-test/t/join_outer_jcl6.test5
-rw-r--r--mysql-test/t/maria_mrr.test5
-rw-r--r--mysql-test/t/myisam.test18
-rw-r--r--mysql-test/t/myisam_icp.test5
-rw-r--r--mysql-test/t/order_by.test5
-rw-r--r--mysql-test/t/parser_stack.test15
-rw-r--r--mysql-test/t/partition_innodb_plugin.test26
-rw-r--r--mysql-test/t/pool_of_threads.test4
-rw-r--r--mysql-test/t/ps.test9
-rw-r--r--mysql-test/t/query_cache.test12
-rw-r--r--mysql-test/t/select.test41
-rw-r--r--mysql-test/t/select_jcl6.test5
-rw-r--r--mysql-test/t/subselect.test288
-rw-r--r--mysql-test/t/subselect2.test31
-rw-r--r--mysql-test/t/subselect3.test11
-rw-r--r--mysql-test/t/subselect3_jcl6.test3
-rw-r--r--mysql-test/t/subselect4.test62
-rw-r--r--mysql-test/t/subselect_cache.test8
-rw-r--r--mysql-test/t/subselect_mat_cost_bugs.test12
-rw-r--r--mysql-test/t/subselect_no_mat.test5
-rw-r--r--mysql-test/t/subselect_no_opts.test4
-rw-r--r--mysql-test/t/subselect_no_scache.test4
-rw-r--r--mysql-test/t/subselect_no_semijoin.test4
-rw-r--r--mysql-test/t/subselect_partial_match.test25
-rw-r--r--mysql-test/t/subselect_sj.test171
-rw-r--r--mysql-test/t/subselect_sj2.test16
-rw-r--r--mysql-test/t/subselect_sj2_jcl6.test93
-rw-r--r--mysql-test/t/subselect_sj2_mat.test29
-rw-r--r--mysql-test/t/subselect_sj_aria.test76
-rw-r--r--mysql-test/t/subselect_sj_jcl6.test5
-rw-r--r--mysql-test/t/subselect_sj_mat.test103
-rw-r--r--mysql-test/t/subselect_sj_nonmerged.test6
-rw-r--r--mysql-test/t/table_elim.test4
-rw-r--r--mysql-test/t/trigger.test40
-rw-r--r--mysql-test/t/type_datetime.test5
-rw-r--r--mysql-test/t/type_newdecimal.test21
-rw-r--r--mysql-test/t/union.test4
-rw-r--r--mysql-test/t/variables-notembedded.test7
-rw-r--r--mysql-test/t/view.test5
-rw-r--r--mysql-test/t/view_grant.test361
-rw-r--r--mysql-test/valgrind.supp24
-rw-r--r--mysys/CMakeLists.txt2
-rw-r--r--mysys/charset.c3
-rw-r--r--mysys/errors.c3
-rw-r--r--mysys/mf_iocache.c3
-rw-r--r--mysys/mf_keycache.c3
-rw-r--r--mysys/mf_loadpath.c3
-rw-r--r--mysys/my_alloc.c3
-rw-r--r--mysys/my_bitmap.c2
-rw-r--r--mysys/my_copy.c3
-rw-r--r--mysys/my_file.c3
-rw-r--r--mysys/my_gethwaddr.c3
-rw-r--r--mysys/my_getncpus.c3
-rw-r--r--mysys/my_getopt.c3
-rw-r--r--mysys/my_getsystime.c5
-rw-r--r--mysys/my_getwd.c3
-rw-r--r--mysys/my_handler_errors.h3
-rw-r--r--mysys/my_init.c3
-rw-r--r--mysys/my_malloc.c3
-rw-r--r--mysys/my_redel.c3
-rw-r--r--mysys/my_seek.c3
-rw-r--r--mysys/my_static.c4
-rw-r--r--mysys/my_symlink.c3
-rw-r--r--mysys/my_sync.c3
-rw-r--r--mysys/stacktrace.c3
-rw-r--r--mysys/thr_alarm.c3
-rw-r--r--mysys/thr_lock.c7
-rw-r--r--mysys/thr_mutex.c3
-rw-r--r--plugin/auth_dialog/CMakeLists.txt3
-rw-r--r--plugin/auth_dialog/dialog.c33
-rw-r--r--plugin/auth_pam/Makefile.am16
-rw-r--r--plugin/auth_pam/auth_pam.c130
-rw-r--r--plugin/auth_pam/plug.in4
-rw-r--r--plugin/auth_pam/testing/pam_mariadb_mtr.c87
-rw-r--r--plugin/feedback/feedback.h2
-rw-r--r--plugin/fulltext/plugin_example.c2
-rwxr-xr-xscripts/make_win_bin_dist2
-rw-r--r--scripts/mysql_install_db.sh2
-rwxr-xr-xscripts/mysql_secure_installation.pl.in2
-rw-r--r--scripts/mysql_secure_installation.sh2
-rw-r--r--scripts/mysql_system_tables.sql7
-rw-r--r--scripts/mysql_system_tables_data.sql3
-rw-r--r--scripts/mysqld_multi.sh17
-rw-r--r--scripts/mysqlhotcopy.sh2
-rwxr-xr-xscripts/mytop.sh38
-rw-r--r--sql-common/client.c3
-rw-r--r--sql-common/my_time.c3
-rw-r--r--sql/CMakeLists.txt2
-rw-r--r--sql/authors.h2
-rw-r--r--sql/debug_sync.cc2
-rw-r--r--sql/debug_sync.h2
-rw-r--r--sql/derror.cc19
-rw-r--r--sql/event_data_objects.cc3
-rw-r--r--sql/event_db_repository.cc2
-rw-r--r--sql/event_db_repository.h5
-rw-r--r--sql/event_parse_data.cc2
-rw-r--r--sql/event_parse_data.h2
-rw-r--r--sql/events.cc17
-rw-r--r--sql/field.cc2
-rw-r--r--sql/field.h19
-rw-r--r--sql/field_conv.cc46
-rw-r--r--sql/filesort.cc16
-rw-r--r--sql/gcalc_slicescan.cc108
-rw-r--r--sql/gcalc_slicescan.h5
-rw-r--r--sql/gcalc_tools.cc14
-rw-r--r--sql/gen_lex_hash.cc25
-rw-r--r--sql/ha_ndbcluster.cc2
-rw-r--r--sql/ha_ndbcluster_binlog.cc3
-rw-r--r--sql/ha_partition.cc2
-rw-r--r--sql/ha_partition.h2
-rw-r--r--sql/handler.cc56
-rw-r--r--sql/item.cc32
-rw-r--r--sql/item.h6
-rw-r--r--sql/item_buff.cc3
-rw-r--r--sql/item_create.cc2
-rw-r--r--sql/item_create.h2
-rw-r--r--sql/item_func.cc4
-rw-r--r--sql/item_func.h5
-rw-r--r--sql/item_geofunc.cc202
-rw-r--r--sql/item_row.cc3
-rw-r--r--sql/item_row.h3
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/item_strfunc.h3
-rw-r--r--sql/item_subselect.cc72
-rw-r--r--sql/item_subselect.h53
-rw-r--r--sql/item_sum.cc2
-rw-r--r--sql/item_sum.h2
-rw-r--r--sql/item_timefunc.cc15
-rw-r--r--sql/item_xmlfunc.cc3
-rw-r--r--sql/lock.cc14
-rw-r--r--sql/log.cc1
-rw-r--r--sql/log.h3
-rw-r--r--sql/log_event.cc2
-rw-r--r--sql/log_event.h3
-rw-r--r--sql/log_event_old.cc2
-rw-r--r--sql/message.h4
-rw-r--r--sql/my_decimal.cc3
-rw-r--r--sql/my_decimal.h33
-rw-r--r--sql/mysqld.cc16
-rw-r--r--sql/opt_index_cond_pushdown.cc5
-rw-r--r--sql/opt_range.cc5
-rw-r--r--sql/opt_range.h3
-rw-r--r--sql/opt_subselect.cc1317
-rw-r--r--sql/opt_subselect.h22
-rw-r--r--sql/opt_sum.cc7
-rw-r--r--sql/partition_info.cc3
-rw-r--r--sql/password.c2
-rw-r--r--sql/protocol.cc4
-rw-r--r--sql/records.cc3
-rw-r--r--sql/repl_failsafe.cc3
-rw-r--r--sql/rpl_injector.cc3
-rw-r--r--sql/rpl_mi.h3
-rw-r--r--sql/rpl_record.cc4
-rw-r--r--sql/rpl_record.h4
-rw-r--r--sql/rpl_rli.cc3
-rw-r--r--sql/rpl_rli.h3
-rw-r--r--sql/rpl_utility.cc3
-rw-r--r--sql/rpl_utility.h3
-rw-r--r--sql/set_var.cc2
-rw-r--r--sql/share/errmsg-utf8.txt1
-rw-r--r--sql/slave.cc4
-rw-r--r--sql/slave.h3
-rw-r--r--sql/sp.cc2
-rw-r--r--sql/sp_head.cc17
-rw-r--r--sql/sp_head.h3
-rw-r--r--sql/spatial.h10
-rw-r--r--sql/sql_acl.cc18
-rw-r--r--sql/sql_admin.cc13
-rw-r--r--sql/sql_analyse.cc2
-rw-r--r--sql/sql_base.cc13
-rw-r--r--sql/sql_binlog.cc2
-rw-r--r--sql/sql_cache.cc64
-rw-r--r--sql/sql_cache.h1
-rw-r--r--sql/sql_class.cc39
-rw-r--r--sql/sql_class.h3
-rw-r--r--sql/sql_connect.cc5
-rw-r--r--sql/sql_cursor.cc3
-rw-r--r--sql/sql_db.cc2
-rw-r--r--sql/sql_delete.cc26
-rw-r--r--sql/sql_derived.cc3
-rw-r--r--sql/sql_help.cc3
-rw-r--r--sql/sql_insert.cc34
-rw-r--r--sql/sql_join_cache.cc2
-rw-r--r--sql/sql_lex.cc83
-rw-r--r--sql/sql_lex.h4
-rw-r--r--sql/sql_list.h3
-rw-r--r--sql/sql_load.cc4
-rw-r--r--sql/sql_parse.cc38
-rw-r--r--sql/sql_partition.h3
-rw-r--r--sql/sql_plugin.h3
-rw-r--r--sql/sql_prepare.cc5
-rw-r--r--sql/sql_priv.h6
-rw-r--r--sql/sql_profile.cc4
-rw-r--r--sql/sql_rename.cc3
-rw-r--r--sql/sql_repl.cc5
-rw-r--r--sql/sql_select.cc539
-rw-r--r--sql/sql_select.h365
-rw-r--r--sql/sql_show.cc18
-rw-r--r--sql/sql_string.cc3
-rw-r--r--sql/sql_string.h4
-rw-r--r--sql/sql_table.cc6
-rw-r--r--sql/sql_trigger.cc5
-rw-r--r--sql/sql_trigger.h2
-rw-r--r--sql/sql_udf.cc3
-rw-r--r--sql/sql_union.cc2
-rw-r--r--sql/sql_view.cc33
-rw-r--r--sql/sys_vars.cc2
-rw-r--r--sql/table.cc4
-rw-r--r--sql/table.h20
-rw-r--r--sql/thr_malloc.cc3
-rw-r--r--sql/tztime.cc3
-rw-r--r--sql/udf_example.c3
-rw-r--r--sql/unireg.cc2
-rw-r--r--sql/unireg.h3
-rw-r--r--storage/archive/archive_reader.c2
-rw-r--r--storage/archive/ha_archive.cc2
-rw-r--r--storage/csv/ha_tina.cc3
-rw-r--r--storage/example/ha_example.cc8
-rw-r--r--storage/example/ha_example.h3
-rw-r--r--storage/federated/ha_federated.cc4
-rw-r--r--storage/federated/ha_federated.h3
-rw-r--r--storage/heap/ha_heap.cc2
-rw-r--r--storage/heap/ha_heap.h2
-rw-r--r--storage/heap/hp_hash.c3
-rw-r--r--storage/innobase/btr/btr0cur.c16
-rw-r--r--storage/innobase/btr/btr0pcur.c2
-rw-r--r--storage/innobase/btr/btr0sea.c275
-rw-r--r--storage/innobase/buf/buf0buf.c200
-rw-r--r--storage/innobase/buf/buf0lru.c6
-rw-r--r--storage/innobase/fsp/fsp0fsp.c8
-rw-r--r--storage/innobase/ha/ha0ha.c69
-rw-r--r--storage/innobase/handler/ha_innodb.cc34
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.c2
-rw-r--r--storage/innobase/include/btr0pcur.h8
-rw-r--r--storage/innobase/include/btr0pcur.ic32
-rw-r--r--storage/innobase/include/btr0sea.h34
-rw-r--r--storage/innobase/include/btr0types.h25
-rw-r--r--storage/innobase/include/buf0buf.h44
-rw-r--r--storage/innobase/include/fsp0fsp.h3
-rw-r--r--storage/innobase/include/ha0ha.h23
-rw-r--r--storage/innobase/include/ha0ha.ic54
-rw-r--r--storage/innobase/include/mtr0mtr.ic1
-rw-r--r--storage/innobase/include/row0upd.ic1
-rw-r--r--storage/innobase/include/sync0sync.h1
-rw-r--r--storage/innobase/page/page0page.c12
-rw-r--r--storage/innobase/row/row0ins.c25
-rw-r--r--storage/innobase/row/row0mysql.c3
-rw-r--r--storage/innobase/sync/sync0sync.c1
-rw-r--r--storage/maria/ha_maria.cc42
-rw-r--r--storage/maria/ha_maria.h5
-rw-r--r--storage/maria/ma_bitmap.c6
-rw-r--r--storage/maria/ma_blockrec.c2
-rw-r--r--storage/maria/ma_check.c11
-rw-r--r--storage/maria/ma_delete.c6
-rw-r--r--storage/maria/ma_ft_nlq_search.c2
-rw-r--r--storage/maria/ma_key_recover.c5
-rw-r--r--storage/maria/ma_locking.c2
-rw-r--r--storage/maria/ma_loghandler.c6
-rw-r--r--storage/maria/ma_open.c5
-rw-r--r--storage/maria/ma_recovery.c6
-rw-r--r--storage/maria/ma_rt_index.c2
-rw-r--r--storage/maria/ma_write.c10
-rw-r--r--storage/maria/unittest/ma_test_recovery.expected192
-rw-r--r--storage/myisam/ft_nlq_search.c3
-rw-r--r--storage/myisam/ft_stopwords.c2
-rw-r--r--storage/myisam/fulltext.h3
-rw-r--r--storage/myisam/ha_myisam.cc18
-rw-r--r--storage/myisam/ha_myisam.h2
-rw-r--r--storage/myisam/mi_check.c2
-rw-r--r--storage/myisam/mi_create.c2
-rw-r--r--storage/myisam/mi_delete_all.c8
-rw-r--r--storage/myisam/mi_delete_table.c3
-rw-r--r--storage/myisam/mi_dynrec.c3
-rw-r--r--storage/myisam/mi_extra.c3
-rw-r--r--storage/myisam/mi_locking.c3
-rw-r--r--storage/myisam/mi_open.c3
-rw-r--r--storage/myisam/mi_page.c3
-rw-r--r--storage/myisam/mi_range.c2
-rw-r--r--storage/myisam/mi_rnext.c3
-rw-r--r--storage/myisam/mi_search.c3
-rw-r--r--storage/myisam/mi_test1.c2
-rw-r--r--storage/myisam/mi_test2.c3
-rw-r--r--storage/myisam/mi_unique.c3
-rw-r--r--storage/myisam/mi_update.c2
-rw-r--r--storage/myisam/mi_write.c2
-rw-r--r--storage/myisam/myisam_ftdump.c3
-rw-r--r--storage/myisam/myisamchk.c3
-rw-r--r--storage/myisam/myisamdef.h2
-rw-r--r--storage/myisam/myisamlog.c3
-rw-r--r--storage/myisam/myisampack.c2
-rw-r--r--storage/myisam/rt_index.c2
-rw-r--r--storage/myisam/rt_split.c3
-rw-r--r--storage/myisam/sort.c3
-rw-r--r--storage/myisam/sp_test.c2
-rw-r--r--storage/myisammrg/ha_myisammrg.cc2
-rw-r--r--storage/myisammrg/ha_myisammrg.h2
-rw-r--r--storage/myisammrg/myrg_open.c3
-rw-r--r--storage/pbxt/src/cache_xt.cc2
-rw-r--r--storage/pbxt/src/lock_xt.h8
-rw-r--r--storage/xtradb/fil/fil0fil.c10
-rw-r--r--storage/xtradb/handler/ha_innodb.cc24
-rw-r--r--storage/xtradb/include/srv0srv.h2
-rw-r--r--storage/xtradb/os/os0file.c56
-rw-r--r--storage/xtradb/row/row0ins.c2
-rw-r--r--storage/xtradb/srv/srv0srv.c2
-rw-r--r--strings/CMakeLists.txt2
-rw-r--r--strings/conf_to_src.c1
-rw-r--r--strings/ctype-big5.c2
-rw-r--r--strings/ctype-bin.c3
-rw-r--r--strings/ctype-cp932.c2
-rw-r--r--strings/ctype-czech.c3
-rw-r--r--strings/ctype-euc_kr.c2
-rw-r--r--strings/ctype-extra.c3
-rw-r--r--strings/ctype-gb2312.c2
-rw-r--r--strings/ctype-gbk.c2
-rw-r--r--strings/ctype-latin1.c2
-rw-r--r--strings/ctype-mb.c2
-rw-r--r--strings/ctype-simple.c3
-rw-r--r--strings/ctype-sjis.c2
-rw-r--r--strings/ctype-tis620.c17
-rw-r--r--strings/ctype-uca.c3
-rw-r--r--strings/ctype-ucs2.c2
-rw-r--r--strings/ctype-ujis.c2
-rw-r--r--strings/ctype-utf8.c3
-rw-r--r--strings/ctype-win1250ch.c2
-rw-r--r--strings/ctype.c1
-rw-r--r--strings/decimal.c21
-rw-r--r--strings/do_ctype.c3
-rw-r--r--strings/dump_map.c1
-rw-r--r--strings/my_strchr.c2
-rw-r--r--strings/my_vsnprintf.c2
-rw-r--r--strings/str_alloc.c3
-rw-r--r--strings/strappend.c10
-rw-r--r--strings/strcend.c9
-rw-r--r--strings/strmake.c3
-rw-r--r--strings/uca-dump.c1
-rw-r--r--strings/utr11-dump.c1
-rw-r--r--support-files/compiler_warnings.supp1
-rw-r--r--tests/mysql_client_test.c87
-rw-r--r--unittest/examples/no_plan-t.c2
-rw-r--r--unittest/examples/skip-t.c3
-rw-r--r--unittest/examples/skip_all-t.c3
-rw-r--r--unittest/examples/todo-t.c3
-rw-r--r--unittest/mysys/bitmap-t.c3
-rw-r--r--unittest/mytap/t/basic-t.c3
-rw-r--r--unittest/mytap/tap.h2
-rw-r--r--unittest/strings/strings-t.c2
-rw-r--r--vio/viosocket.c4
-rw-r--r--vio/viosslfactories.c3
750 files changed, 17312 insertions, 7063 deletions
diff --git a/.bzrignore b/.bzrignore
index 4dca2e49338..b34267b09f4 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1133,3 +1133,5 @@ 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/libmysqld_exports_file.cc
+libmysqld/gcalc_slicescan.cc
+libmysqld/gcalc_tools.cc
diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh
index fb4add74d8b..1bbc47341c9 100644
--- a/BUILD/FINISH.sh
+++ b/BUILD/FINISH.sh
@@ -18,6 +18,7 @@
cflags="$c_warnings $extra_flags $EXTRA_FLAGS $EXTRA_CFLAGS"
cxxflags="$cxx_warnings $base_cxxflags $extra_flags $EXTRA_FLAGS $EXTRA_CXXFLAGS"
extra_configs="$extra_configs $local_infile_configs $EXTRA_CONFIGS"
+
configure="./configure $base_configs $extra_configs"
commands="\
diff --git a/BUILD/check-cpu b/BUILD/check-cpu
index 070e7de0125..ad8816dc421 100755
--- a/BUILD/check-cpu
+++ b/BUILD/check-cpu
@@ -1,4 +1,19 @@
#!/bin/sh
+# Copyright (c) 2005, 2010, Oracle and/or its affiliates.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
#
# Check cpu of current machine and find the
# best compiler optimization flags for gcc
diff --git a/BUILD/compile-dist b/BUILD/compile-dist
index 754874b1b2b..becfea638f8 100755
--- a/BUILD/compile-dist
+++ b/BUILD/compile-dist
@@ -1,4 +1,20 @@
#!/bin/sh
+# Copyright (c) 2004-2008 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
+# Use is subject to license terms.
+#
+# 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
+
#
# This script's purpose is to update the automake/autoconf helper scripts and
# to run a plain "configure" without any special compile flags. Only features
diff --git a/BUILD/compile-pentium-icc-valgrind-max b/BUILD/compile-pentium-icc-valgrind-max
index b26df4b1bd6..4858f796fab 100755
--- a/BUILD/compile-pentium-icc-valgrind-max
+++ b/BUILD/compile-pentium-icc-valgrind-max
@@ -1,4 +1,18 @@
#! /bin/sh
+# Copyright (c) 2005, 2010, Oracle and/or its affiliates.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/BUILD/compile-pentium-valgrind-max b/BUILD/compile-pentium-valgrind-max
index 7a2c6ae4980..c4cb1845ba1 100755
--- a/BUILD/compile-pentium-valgrind-max
+++ b/BUILD/compile-pentium-valgrind-max
@@ -1,4 +1,18 @@
#! /bin/sh
+# Copyright (c) 2002, 2010, Oracle and/or its affiliates.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/BUILD/compile-pentium64-valgrind-max b/BUILD/compile-pentium64-valgrind-max
index cec7f734ef5..beb2ee2532c 100755
--- a/BUILD/compile-pentium64-valgrind-max
+++ b/BUILD/compile-pentium64-valgrind-max
@@ -1,4 +1,18 @@
#! /bin/sh
+# Copyright (c) 2005, 2010, Oracle and/or its affiliates.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/BUILD/compile-solaris-amd64-forte b/BUILD/compile-solaris-amd64-forte
index 8e9913d6ddf..a55627d2401 100755
--- a/BUILD/compile-solaris-amd64-forte
+++ b/BUILD/compile-solaris-amd64-forte
@@ -1,4 +1,19 @@
#!/bin/sh
+# Copyright (c) 2007 MySQL AB, 2008 Sun Microsystems, Inc.
+# Use is subject to license terms.
+#
+# 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
# See file compile-solaris-amd64 for basic pre-requisites.
@@ -9,8 +24,7 @@
# After installing, add /opt/SUNWspro/bin to your $PATH
-
-gmake -k maintainer-clean || true
+gmake -k clean || true
/bin/rm -f */.deps/*.P config.cache
path=`dirname $0`
diff --git a/BUILD/compile-solaris-sparc b/BUILD/compile-solaris-sparc
index df3cf1e26c3..ddecb0e3436 100755
--- a/BUILD/compile-solaris-sparc
+++ b/BUILD/compile-solaris-sparc
@@ -1,4 +1,19 @@
#! /bin/sh
+# Copyright (c) 2000-2002, 2005-2007 MySQL AB, 2008 Sun Microsystems, Inc.
+# Use is subject to license terms.
+#
+# 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
make -k clean || true
/bin/rm -f */.deps/*.P config.cache
diff --git a/BUILD/compile-solaris-sparc-forte b/BUILD/compile-solaris-sparc-forte
index 14cb3ce1ff9..cf17fa49c51 100755
--- a/BUILD/compile-solaris-sparc-forte
+++ b/BUILD/compile-solaris-sparc-forte
@@ -1,4 +1,19 @@
#! /bin/sh
+# Copyright (c) 2001, 2002, 2005, 2007 MySQL AB, 2008 Sun Microsystems, Inc.
+# Use is subject to license terms.
+#
+# 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
# Copyright (c) 2001, 2002, 2005, 2007 MySQL AB, 2008 Sun Microsystems, Inc.
# Use is subject to license terms.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3cae2e95e3e..27c43f1328a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,4 +1,5 @@
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2011, Oracle and/or its affiliates.
+# 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
diff --git a/client/my_readline.h b/client/my_readline.h
index d288a33e1cc..11ace987b44 100644
--- a/client/my_readline.h
+++ b/client/my_readline.h
@@ -2,7 +2,7 @@
#define CLIENT_MY_READLINE_INCLUDED
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/client/mysql.cc b/client/mysql.cc
index 1074a7aaaed..e74495dcf8d 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1,5 +1,5 @@
/* Copyright (C) 2000-2009 MySQL AB
- Copyright 2000, 2010, Oracle and/or its affiliates.
+ Copyright 2000, 2010-2011, Oracle and/or its affiliates.
Copyright 2000-2010 Monty Program Ab
This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,11 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#define COPYRIGHT_NOTICE "\
+This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL v2 license\n"
/* mysql command tool
* Commands compatible with mSQL by David J. Hughes
@@ -108,7 +111,6 @@ extern "C" {
#endif
#include "completion_hash.h"
-#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
#define PROMPT_CHAR '\\'
#define DEFAULT_DELIMITER ";"
@@ -1190,7 +1192,7 @@ int main(int argc,char *argv[])
mysql_thread_id(&mysql), server_version_string(&mysql));
put_info((char*) glob_buffer.ptr(),INFO_INFO);
- put_info(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"), INFO_INFO);
+ put_info(COPYRIGHT_NOTICE, INFO_INFO);
#ifdef HAVE_READLINE
initialize_readline((char*) my_progname);
@@ -1621,7 +1623,7 @@ static void usage(int version)
if (version)
return;
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
+ printf("%s", COPYRIGHT_NOTICE);
printf("Usage: %s [OPTIONS] [database]\n", my_progname);
my_print_help(my_long_options);
print_defaults("my", load_default_groups);
@@ -2732,6 +2734,8 @@ static int reconnect(void)
}
if (!connected)
return put_info("Can't connect to the server\n",INFO_ERROR);
+ my_free(server_version);
+ server_version= 0;
/* purecov: end */
return 0;
}
@@ -4343,9 +4347,10 @@ char *get_arg(char *line, my_bool get_next_arg)
string, and the "dialog" plugin will free() it.
*/
-extern "C" char *mysql_authentication_dialog_ask(MYSQL *mysql, int type,
- const char *prompt,
- char *buf, int buf_len)
+MYSQL_PLUGIN_EXPORT
+char *mysql_authentication_dialog_ask(MYSQL *mysql, int type,
+ const char *prompt,
+ char *buf, int buf_len)
{
char *s=buf;
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 424d847c187..e2c2d881654 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -1,5 +1,7 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
- Copyright (C) 2010 Monty Program Ab
+/*
+ Copyright (C) 2000 MySQL AB
+ Copyright (c) 2006, 2011, Oracle and/or its affiliates.
+ Copyright (C) 2010-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
@@ -248,7 +250,6 @@ get_one_option(int optid, const struct my_option *opt,
switch (optid) {
case '?':
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
printf("%s Ver %s Distrib %s, for %s (%s)\n",
my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010"));
diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc
index 4a691ff4e14..b12ea164aab 100644
--- a/client/mysqladmin.cc
+++ b/client/mysqladmin.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,7 +22,6 @@
#include <sys/stat.h>
#include <mysql.h>
#include <sql_common.h>
-#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
#define ADMIN_VERSION "9.0"
#define MAX_MYSQL_VAR 512
@@ -699,7 +699,9 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv)
case ADMIN_VER:
new_line=1;
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
+ puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc,\n"
+ "2009 Monty Program Ab");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
printf("Server version\t\t%s\n", mysql_get_server_info(mysql));
printf("Protocol version\t%d\n", mysql_get_proto_info(mysql));
printf("Connection\t\t%s\n",mysql_get_host_info(mysql));
@@ -1171,7 +1173,9 @@ static void print_version(void)
static void usage(void)
{
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
+ puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc,\n"
+ "2009 Monty Program Ab");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
puts("Administration program for the mysqld daemon.");
printf("Usage: %s [OPTIONS] command command....\n", my_progname);
my_print_help(my_long_options);
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index 8869c3ac81b..5ffde0cf1b0 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -37,7 +37,6 @@
#include "sql_priv.h"
#include "log_event.h"
#include "sql_common.h"
-#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
#include "sql_string.h" // needed for Rpl_filter
#include "sql_list.h" // needed for Rpl_filter
@@ -1446,7 +1445,10 @@ static void print_version()
static void usage()
{
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
+ puts("By Monty and Sasha, for your professional use\n\
+This software comes with NO WARRANTY: This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL license.\n");
+
printf("\
Dumps a MySQL binary log in a format usable for viewing or for piping to\n\
the mysql command line client.\n\n");
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 68456d59041..f983c952c4c 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* Copyright (C) 2000 MySQL AB & Jani Tolonen
+ Copyright (c) 2001, 2011, Oracle and/or its affiliates.
Copyright (C) 2010-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
@@ -24,7 +25,6 @@
#include <mysql_version.h>
#include <mysqld_error.h>
#include <sslopt-vars.h>
-#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
/* Exit codes */
@@ -229,7 +229,9 @@ static void usage(void)
{
DBUG_ENTER("usage");
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
+ puts("By Jani Tolonen, 2001-04-20, MySQL Development Team.\n");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,");
+ puts("and you are welcome to modify and redistribute it under the GPL license.\n");
printf("Usage: %s [OPTIONS] database [tables]\n", my_progname);
printf("OR %s [OPTIONS] --databases DB1 [DB2 DB3...]\n",
my_progname);
diff --git a/client/mysqldump.c b/client/mysqldump.c
index bfdbf90d313..2b6fc597dbb 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -55,8 +55,6 @@
#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
-#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
-
/* Exit codes */
#define EX_USAGE 1
@@ -602,7 +600,8 @@ static void short_usage_sub(void)
static void usage(void)
{
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
+ puts("By Igor Romanenko, Monty, Jani & Sinisa and others.");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n");
puts("Dumping structure and contents of MySQL databases and tables.");
short_usage_sub();
print_defaults("my",load_default_groups);
diff --git a/client/mysqlimport.c b/client/mysqlimport.c
index fabec74052d..e721b841f06 100644
--- a/client/mysqlimport.c
+++ b/client/mysqlimport.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,8 +18,14 @@
/*
** mysqlimport.c - Imports all given files
** into a table(s).
+**
+** *************************
+** * *
+** * AUTHOR: Monty & Jani *
+** * DATE: June 24, 1997 *
+** * *
+** *************************
*/
-
#define IMPORT_VERSION "3.7"
#include "client_priv.h"
@@ -38,8 +44,6 @@ pthread_mutex_t counter_mutex;
pthread_cond_t count_threshhold;
#endif
-#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
-
static void db_error_with_table(MYSQL *mysql, char *table);
static void db_error(MYSQL *mysql);
static char *field_escape(char *to,const char *from,uint length);
@@ -201,9 +205,10 @@ static void print_version(void)
static void usage(void)
{
+ puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.");
+ puts("Copyright 2008-2011 Oracle and Monty Program Ab.");
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
- printf("\
+ printf("\n\
Loads tables from text files in various formats. The base name of the\n\
text file must be the name of the table that should be used.\n\
If one uses sockets to connect to the MySQL server, the server will open and\n\
diff --git a/client/mysqlshow.c b/client/mysqlshow.c
index 1f299753587..f80f747b1ad 100644
--- a/client/mysqlshow.c
+++ b/client/mysqlshow.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -27,7 +27,6 @@
#include <signal.h>
#include <stdarg.h>
#include <sslopt-vars.h>
-#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
static char * host=0, *opt_password=0, *user=0;
static my_bool opt_show_keys= 0, opt_compress= 0, opt_count=0, opt_status= 0;
@@ -265,7 +264,9 @@ static void print_version(void)
static void usage(void)
{
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011)"));
+ puts("Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.");
+ puts("Copyright 2008-2011 Oracle and Monty Program Ab.");
+ puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license.\n");
puts("Shows the structure of a MySQL database (databases, tables, and columns).\n");
printf("Usage: %s [OPTIONS] [database [table [column]]]\n",my_progname);
puts("\n\
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index 0f8a1edc476..955a31c1872 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 89e74a56bfc..c1ff504bb2a 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009-2011 Monty Program Ab.
+ Copyright (c) 2009-2012 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
@@ -23,6 +23,14 @@
http://dev.mysql.com/doc/mysqltest/en/index.html
Please keep the test framework tools identical in all versions!
+
+ Written by:
+ Sasha Pachev <sasha@mysql.com>
+ Matt Wagner <matt@mysql.com>
+ Monty
+ Jani
+ Holyfoot
+ And many others
*/
#define MTEST_VERSION "3.3"
@@ -46,8 +54,6 @@
#include <signal.h>
#include <my_stacktrace.h>
-#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
-
#ifdef __WIN__
#include <crtdbg.h>
#define SIGNAL_FMT "exception 0x%x"
@@ -304,7 +310,6 @@ struct st_connection
pthread_mutex_t result_mutex;
pthread_cond_t result_cond;
int query_done;
- my_bool has_thread;
#endif /*EMBEDDED_LIBRARY*/
};
@@ -762,7 +767,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,
@@ -3014,6 +3020,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));
@@ -3059,6 +3066,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)
@@ -3068,10 +3082,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);
@@ -3304,7 +3325,7 @@ void do_remove_file(struct st_command *command)
' ');
DBUG_PRINT("info", ("removing file: %s", ds_filename.str));
- error= my_delete(ds_filename.str, MYF(disable_warnings ? 0 : MY_WME)) != 0;
+ error= my_delete_allow_opened(ds_filename.str, MYF(disable_warnings ? 0 : MY_WME)) != 0;
handle_command_error(command, error, my_errno);
dynstr_free(&ds_filename);
DBUG_VOID_RETURN;
@@ -6625,7 +6646,8 @@ void print_version(void)
void usage()
{
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
+ printf("MySQL AB, by Sasha, Matt, Monty & Jani and others\n");
+ printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
printf("Runs a test against the mysql server and compares output with a results file.\n\n");
printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname);
my_print_help(my_long_options);
@@ -8098,7 +8120,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);
}
@@ -8602,6 +8624,9 @@ int main(int argc, char **argv)
if (opt_protocol)
mysql_options(con->mysql,MYSQL_OPT_PROTOCOL,(char*)&opt_protocol);
+ if (opt_plugin_dir && *opt_plugin_dir)
+ mysql_options(con->mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir);
+
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
if (opt_use_ssl)
@@ -10495,17 +10520,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)
@@ -10513,7 +10537,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;
@@ -10525,11 +10550,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)
@@ -10578,3 +10606,32 @@ static int setenv(const char *name, const char *value, int overwrite)
return 0;
}
#endif
+
+/*
+ for the purpose of testing (see dialog.test)
+ we replace default mysql_authentication_dialog_ask function with the one,
+ that always reads from stdin with explicit echo.
+
+*/
+MYSQL_PLUGIN_EXPORT
+char *mysql_authentication_dialog_ask(MYSQL *mysql, int type,
+ const char *prompt,
+ char *buf, int buf_len)
+{
+ char *s=buf;
+
+ fputs(prompt, stdout);
+ fputs(" ", stdout);
+
+ if (!fgets(buf, buf_len-1, stdin))
+ buf[0]= 0;
+ else if (buf[0] && (s= strend(buf))[-1] == '\n')
+ s[-1]= 0;
+
+ for (s= buf; *s; s++)
+ fputc(type == 2 ? '*' : *s, stdout);
+
+ fputc('\n', stdout);
+
+ return buf;
+}
diff --git a/client/readline.cc b/client/readline.cc
index e451baff341..791a044e0e1 100644
--- a/client/readline.cc
+++ b/client/readline.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/client/sql_string.cc.dontuse b/client/sql_string.cc.dontuse
index 26181722b11..8d1e19de71c 100644
--- a/client/sql_string.cc.dontuse
+++ b/client/sql_string.cc.dontuse
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/client/sql_string.h.dontuse b/client/sql_string.h.dontuse
index 26f3b330f20..fc302110513 100644
--- a/client/sql_string.h.dontuse
+++ b/client/sql_string.h.dontuse
@@ -1,7 +1,8 @@
#ifndef SQL_STRING_INCLUDED
#define SQL_STRING_INCLUDED
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/cmd-line-utils/libedit/README b/cmd-line-utils/libedit/README
index 0b698a6150d..c4bc1554b03 100644
--- a/cmd-line-utils/libedit/README
+++ b/cmd-line-utils/libedit/README
@@ -2,7 +2,7 @@ An approximate method to merge from upstream is:
# Fetch latest from upstream (we also include some compat stuff)
$ CVS_RSH=ssh; export CVS_RSH
- $ CVSROOT="anoncvs@stripped:/cvsroot"
+ $ CVSROOT="anoncvs@anoncvs.netbsd.org:/cvsroot"
$ cvs co -d libedit -P src/lib/libedit
$ mkdir libedit/np
$ for f in src/common/lib/libc/string/strlcat.c \
@@ -24,13 +24,13 @@ An approximate method to merge from upstream is:
# Rename files to match our naming
$ mv makelist makelist.sh
- $ mv term.h el_term.h
+ $ mv terminal.h el_terminal.h
# Remove NetBSD-specific bits
$ for file in $(find . -type f)
> do
> cp ${file} ${file}.orig
- > sed -e 's/#include "term.h"/#include "el_term.h"/g' \
+ > sed -e 's/#include "terminal.h"/#include "el_terminal.h"/g' \
> -e 's/sig_handler/el_sig_handler/g' \
> -e 's/isprint/el_isprint/g' \
> -e '/^__RCSID/d' \
@@ -42,9 +42,9 @@ then merge remaining bits by hand. All MySQL-specific changes should be
marked with XXXMYSQL to make them easier to identify and merge. To generate
a 'clean' diff against upstream you can use the above commands but use
- cvs co -D "2009/02/06 20:09:00" [..]
+ cvs co -D "2011/10/23 17:37:55" [..]
to fetch the baseline of most recent merge.
-Please feed any fixes to Jonathan Perkin <jperkin@stripped> who will endeavour
-to merge them upstream and keep diffs minimal.
+Please feed any fixes to Jonathan Perkin <jonathan.perkin@oracle.com> who will
+endeavour to merge them upstream and keep diffs minimal.
diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c
index e4823db7147..647a5afe439 100644
--- a/cmd-line-utils/libedit/chared.c
+++ b/cmd-line-utils/libedit/chared.c
@@ -1,4 +1,4 @@
-/* $NetBSD: chared.c,v 1.26 2009/02/06 12:45:25 sketch Exp $ */
+/* $NetBSD: chared.c,v 1.36 2011/10/23 17:37:55 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -59,13 +59,13 @@ cv_undo(EditLine *el)
{
c_undo_t *vu = &el->el_chared.c_undo;
c_redo_t *r = &el->el_chared.c_redo;
- unsigned int size;
+ size_t size;
/* Save entire line for undo */
- size = el->el_line.lastchar - el->el_line.buffer;
- vu->len = size;
- vu->cursor = el->el_line.cursor - el->el_line.buffer;
- memcpy(vu->buf, el->el_line.buffer, size);
+ size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
+ vu->len = (ssize_t)size;
+ vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
+ (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
/* save command info for redo */
r->count = el->el_state.doingarg ? el->el_state.argument : 0;
@@ -79,11 +79,11 @@ cv_undo(EditLine *el)
* Save yank/delete data for paste
*/
protected void
-cv_yank(EditLine *el, const char *ptr, int size)
+cv_yank(EditLine *el, const Char *ptr, int size)
{
c_kill_t *k = &el->el_chared.c_kill;
- memcpy(k->buf, ptr, size +0u);
+ (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
k->last = k->buf + size;
}
@@ -94,10 +94,10 @@ cv_yank(EditLine *el, const char *ptr, int size)
protected void
c_insert(EditLine *el, int num)
{
- char *cp;
+ Char *cp;
if (el->el_line.lastchar + num >= el->el_line.limit) {
- if (!ch_enlargebufs(el, num +0u))
+ if (!ch_enlargebufs(el, (size_t)num))
return; /* can't go past end of buffer */
}
@@ -118,7 +118,7 @@ c_delafter(EditLine *el, int num)
{
if (el->el_line.cursor + num > el->el_line.lastchar)
- num = el->el_line.lastchar - el->el_line.cursor;
+ num = (int)(el->el_line.lastchar - el->el_line.cursor);
if (el->el_map.current != el->el_map.emacs) {
cv_undo(el);
@@ -126,7 +126,7 @@ c_delafter(EditLine *el, int num)
}
if (num > 0) {
- char *cp;
+ Char *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[num];
@@ -142,7 +142,7 @@ c_delafter(EditLine *el, int num)
protected void
c_delafter1(EditLine *el)
{
- char *cp;
+ Char *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
@@ -159,7 +159,7 @@ c_delbefore(EditLine *el, int num)
{
if (el->el_line.cursor - num < el->el_line.buffer)
- num = el->el_line.cursor - el->el_line.buffer;
+ num = (int)(el->el_line.cursor - el->el_line.buffer);
if (el->el_map.current != el->el_map.emacs) {
cv_undo(el);
@@ -167,7 +167,7 @@ c_delbefore(EditLine *el, int num)
}
if (num > 0) {
- char *cp;
+ Char *cp;
for (cp = el->el_line.cursor - num;
cp <= el->el_line.lastchar;
@@ -185,7 +185,7 @@ c_delbefore(EditLine *el, int num)
protected void
c_delbefore1(EditLine *el)
{
- char *cp;
+ Char *cp;
for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
@@ -198,9 +198,9 @@ c_delbefore1(EditLine *el)
* Return if p is part of a word according to emacs
*/
protected int
-ce__isword(int p)
+ce__isword(Int p)
{
- return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
+ return Isalnum(p) || Strchr(STR("*?_-.[]~="), p) != NULL;
}
@@ -208,11 +208,11 @@ ce__isword(int p)
* Return if p is part of a word according to vi
*/
protected int
-cv__isword(int p)
+cv__isword(Int p)
{
- if (isalnum(p) || p == '_')
+ if (Isalnum(p) || p == '_')
return 1;
- if (isgraph(p))
+ if (Isgraph(p))
return 2;
return 0;
}
@@ -222,24 +222,24 @@ cv__isword(int p)
* Return if p is part of a big word according to vi
*/
protected int
-cv__isWord(int p)
+cv__isWord(Int p)
{
- return (!isspace(p));
+ return !Isspace(p);
}
/* c__prev_word():
* Find the previous word
*/
-protected char *
-c__prev_word(char *p, char *low, int n, int (*wtest)(int))
+protected Char *
+c__prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
{
p--;
while (n--) {
- while ((p >= low) && !(*wtest)((unsigned char) *p))
+ while ((p >= low) && !(*wtest)(*p))
p--;
- while ((p >= low) && (*wtest)((unsigned char) *p))
+ while ((p >= low) && (*wtest)(*p))
p--;
}
@@ -248,117 +248,83 @@ c__prev_word(char *p, char *low, int n, int (*wtest)(int))
if (p < low)
p = low;
/* cp now points where we want it */
- return (p);
+ return p;
}
/* c__next_word():
* Find the next word
*/
-protected char *
-c__next_word(char *p, char *high, int n, int (*wtest)(int))
+protected Char *
+c__next_word(Char *p, Char *high, int n, int (*wtest)(Int))
{
while (n--) {
- while ((p < high) && !(*wtest)((unsigned char) *p))
+ while ((p < high) && !(*wtest)(*p))
p++;
- while ((p < high) && (*wtest)((unsigned char) *p))
+ while ((p < high) && (*wtest)(*p))
p++;
}
if (p > high)
p = high;
/* p now points where we want it */
- return (p);
+ return p;
}
/* cv_next_word():
* Find the next word vi style
*/
-protected char *
-cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
+protected Char *
+cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(Int))
{
int test;
while (n--) {
- test = (*wtest)((unsigned char) *p);
- while ((p < high) && (*wtest)((unsigned char) *p) == test)
+ test = (*wtest)(*p);
+ while ((p < high) && (*wtest)(*p) == test)
p++;
/*
* vi historically deletes with cw only the word preserving the
* trailing whitespace! This is not what 'w' does..
*/
if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
- while ((p < high) && isspace((unsigned char) *p))
+ while ((p < high) && Isspace(*p))
p++;
}
/* p now points where we want it */
if (p > high)
- return (high);
+ return high;
else
- return (p);
+ return p;
}
/* cv_prev_word():
* Find the previous word vi style
*/
-protected char *
-cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
+protected Char *
+cv_prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
{
int test;
p--;
while (n--) {
- while ((p > low) && isspace((unsigned char) *p))
+ while ((p > low) && Isspace(*p))
p--;
- test = (*wtest)((unsigned char) *p);
- while ((p >= low) && (*wtest)((unsigned char) *p) == test)
+ test = (*wtest)(*p);
+ while ((p >= low) && (*wtest)(*p) == test)
p--;
}
p++;
/* p now points where we want it */
if (p < low)
- return (low);
+ return low;
else
- return (p);
+ return p;
}
-#ifdef notdef
-/* c__number():
- * Ignore character p points to, return number appearing after that.
- * A '$' by itself means a big number; "$-" is for negative; '^' means 1.
- * Return p pointing to last char used.
- */
-protected char *
-c__number(
- char *p, /* character position */
- int *num, /* Return value */
- int dval) /* dval is the number to subtract from like $-3 */
-{
- int i;
- int sign = 1;
-
- if (*++p == '^') {
- *num = 1;
- return (p);
- }
- if (*p == '$') {
- if (*++p != '-') {
- *num = 0x7fffffff; /* Handle $ */
- return (--p);
- }
- sign = -1; /* Handle $- */
- ++p;
- }
- for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
- continue;
- *num = (sign < 0 ? dval - i : i);
- return (--p);
-}
-#endif
-
/* cv_delfini():
* Finish vi delete action
*/
@@ -375,7 +341,7 @@ cv_delfini(EditLine *el)
/* sanity */
return;
- size = el->el_line.cursor - el->el_chared.c_vcmd.pos;
+ size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos);
if (size == 0)
size = 1;
el->el_line.cursor = el->el_chared.c_vcmd.pos;
@@ -397,48 +363,26 @@ cv_delfini(EditLine *el)
}
-#ifdef notdef
-/* ce__endword():
- * Go to the end of this word according to emacs
- */
-protected char *
-ce__endword(char *p, char *high, int n)
-{
- p++;
-
- while (n--) {
- while ((p < high) && isspace((unsigned char) *p))
- p++;
- while ((p < high) && !isspace((unsigned char) *p))
- p++;
- }
-
- p--;
- return (p);
-}
-#endif
-
-
/* cv__endword():
* Go to the end of this word according to vi
*/
-protected char *
-cv__endword(char *p, char *high, int n, int (*wtest)(int))
+protected Char *
+cv__endword(Char *p, Char *high, int n, int (*wtest)(Int))
{
int test;
p++;
while (n--) {
- while ((p < high) && isspace((unsigned char) *p))
+ while ((p < high) && Isspace(*p))
p++;
- test = (*wtest)((unsigned char) *p);
- while ((p < high) && (*wtest)((unsigned char) *p) == test)
+ test = (*wtest)(*p);
+ while ((p < high) && (*wtest)(*p) == test)
p++;
}
p--;
- return (p);
+ return p;
}
/* ch_init():
@@ -449,24 +393,29 @@ ch_init(EditLine *el)
{
c_macro_t *ma = &el->el_chared.c_macro;
- el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
+ el->el_line.buffer = el_malloc(EL_BUFSIZ *
+ sizeof(*el->el_line.buffer));
if (el->el_line.buffer == NULL)
- return (-1);
+ return -1;
- (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
+ (void) memset(el->el_line.buffer, 0, EL_BUFSIZ *
+ sizeof(*el->el_line.buffer));
el->el_line.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer;
el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
- el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
+ el->el_chared.c_undo.buf = el_malloc(EL_BUFSIZ *
+ sizeof(*el->el_chared.c_undo.buf));
if (el->el_chared.c_undo.buf == NULL)
- return (-1);
- (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
+ return -1;
+ (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ *
+ sizeof(*el->el_chared.c_undo.buf));
el->el_chared.c_undo.len = -1;
el->el_chared.c_undo.cursor = 0;
- el->el_chared.c_redo.buf = (char *) el_malloc(EL_BUFSIZ);
+ el->el_chared.c_redo.buf = el_malloc(EL_BUFSIZ *
+ sizeof(*el->el_chared.c_redo.buf));
if (el->el_chared.c_redo.buf == NULL)
- return (-1);
+ return -1;
el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
@@ -474,12 +423,16 @@ ch_init(EditLine *el)
el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = el->el_line.buffer;
- el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
+ el->el_chared.c_kill.buf = el_malloc(EL_BUFSIZ *
+ sizeof(*el->el_chared.c_kill.buf));
if (el->el_chared.c_kill.buf == NULL)
- return (-1);
- (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
+ return -1;
+ (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ *
+ sizeof(*el->el_chared.c_kill.buf));
el->el_chared.c_kill.mark = el->el_line.buffer;
el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
+ el->el_chared.c_resizefun = NULL;
+ el->el_chared.c_resizearg = NULL;
el->el_map.current = el->el_map.key;
@@ -491,10 +444,10 @@ ch_init(EditLine *el)
ma->level = -1;
ma->offset = 0;
- ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *));
+ ma->macro = el_malloc(EL_MAXMACRO * sizeof(*ma->macro));
if (ma->macro == NULL)
- return (-1);
- return (0);
+ return -1;
+ return 0;
}
/* ch_reset():
@@ -529,12 +482,11 @@ ch_reset(EditLine *el, int mclear)
}
private void
-ch__clearmacro(el)
- EditLine *el;
+ch__clearmacro(EditLine *el)
{
c_macro_t *ma = &el->el_chared.c_macro;
while (ma->level >= 0)
- el_free((ptr_t)ma->macro[ma->level--]);
+ el_free(ma->macro[ma->level--]);
}
/* ch_enlargebufs():
@@ -542,14 +494,12 @@ ch__clearmacro(el)
* Returns 1 if successful, 0 if not.
*/
protected int
-ch_enlargebufs(el, addlen)
- EditLine *el;
- size_t addlen;
+ch_enlargebufs(EditLine *el, size_t addlen)
{
size_t sz, newsz;
- char *newbuffer, *oldbuf, *oldkbuf;
+ Char *newbuffer, *oldbuf, *oldkbuf;
- sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
+ sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
newsz = sz * 2;
/*
* If newly required length is longer than current buffer, we need
@@ -563,12 +513,12 @@ ch_enlargebufs(el, addlen)
/*
* Reallocate line buffer.
*/
- newbuffer = el_realloc(el->el_line.buffer, newsz);
+ newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
- (void) memset(&newbuffer[sz], 0, newsz - sz);
+ (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
oldbuf = el->el_line.buffer;
@@ -581,12 +531,13 @@ ch_enlargebufs(el, addlen)
/*
* Reallocate kill buffer.
*/
- newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz);
+ newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz *
+ sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
- (void) memset(&newbuffer[sz], 0, newsz - sz);
+ (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
oldkbuf = el->el_chared.c_kill.buf;
@@ -599,15 +550,17 @@ ch_enlargebufs(el, addlen)
/*
* Reallocate undo buffer.
*/
- newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz);
+ newbuffer = el_realloc(el->el_chared.c_undo.buf,
+ newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
- (void) memset(&newbuffer[sz], 0, newsz - sz);
+ (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
el->el_chared.c_undo.buf = newbuffer;
- newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
+ newbuffer = el_realloc(el->el_chared.c_redo.buf,
+ newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
el->el_chared.c_redo.pos = newbuffer +
@@ -621,6 +574,8 @@ ch_enlargebufs(el, addlen)
/* Safe to set enlarged buffer size */
el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE];
+ if (el->el_chared.c_resizefun)
+ (*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg);
return 1;
}
@@ -630,20 +585,20 @@ ch_enlargebufs(el, addlen)
protected void
ch_end(EditLine *el)
{
- el_free((ptr_t) el->el_line.buffer);
+ el_free(el->el_line.buffer);
el->el_line.buffer = NULL;
el->el_line.limit = NULL;
- el_free((ptr_t) el->el_chared.c_undo.buf);
+ el_free(el->el_chared.c_undo.buf);
el->el_chared.c_undo.buf = NULL;
- el_free((ptr_t) el->el_chared.c_redo.buf);
+ el_free(el->el_chared.c_redo.buf);
el->el_chared.c_redo.buf = NULL;
el->el_chared.c_redo.pos = NULL;
el->el_chared.c_redo.lim = NULL;
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
- el_free((ptr_t) el->el_chared.c_kill.buf);
+ el_free(el->el_chared.c_kill.buf);
el->el_chared.c_kill.buf = NULL;
ch_reset(el, 1);
- el_free((ptr_t) el->el_chared.c_macro.macro);
+ el_free(el->el_chared.c_macro.macro);
el->el_chared.c_macro.macro = NULL;
}
@@ -652,21 +607,21 @@ ch_end(EditLine *el)
* Insert string at cursorI
*/
public int
-el_insertstr(EditLine *el, const char *s)
+FUN(el,insertstr)(EditLine *el, const Char *s)
{
size_t len;
- if ((len = strlen(s)) == 0)
- return (-1);
+ if ((len = Strlen(s)) == 0)
+ return -1;
if (el->el_line.lastchar + len >= el->el_line.limit) {
if (!ch_enlargebufs(el, len))
- return (-1);
+ return -1;
}
c_insert(el, (int)len);
while (*s)
*el->el_line.cursor++ = *s++;
- return (0);
+ return 0;
}
@@ -692,15 +647,15 @@ el_deletestr(EditLine *el, int n)
* Get a string
*/
protected int
-c_gets(EditLine *el, char *buf, const char *prompt)
+c_gets(EditLine *el, Char *buf, const Char *prompt)
{
- char ch;
- int len;
- char *cp = el->el_line.buffer;
+ Char ch;
+ ssize_t len;
+ Char *cp = el->el_line.buffer;
if (prompt) {
- len = strlen(prompt);
- memcpy(cp, prompt, len + 0u);
+ len = (ssize_t)Strlen(prompt);
+ (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
cp += len;
}
len = 0;
@@ -711,7 +666,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
el->el_line.lastchar = cp + 1;
re_refresh(el);
- if (el_getc(el, &ch) != 1) {
+ if (FUN(el,getc)(el, &ch) != 1) {
ed_end_of_file(el, 0);
len = -1;
break;
@@ -721,7 +676,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
case 0010: /* Delete and backspace */
case 0177:
- if (len <= 0) {
+ if (len == 0) {
len = -1;
break;
}
@@ -735,8 +690,8 @@ c_gets(EditLine *el, char *buf, const char *prompt)
break;
default:
- if (len >= EL_BUFSIZ - 16)
- term_beep(el);
+ if (len >= (ssize_t)(EL_BUFSIZ - 16))
+ terminal_beep(el);
else {
buf[len++] = ch;
*cp++ = ch;
@@ -749,7 +704,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
el->el_line.buffer[0] = '\0';
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
- return len;
+ return (int)len;
}
@@ -759,18 +714,26 @@ c_gets(EditLine *el, char *buf, const char *prompt)
protected int
c_hpos(EditLine *el)
{
- char *ptr;
+ Char *ptr;
/*
* Find how many characters till the beginning of this line.
*/
if (el->el_line.cursor == el->el_line.buffer)
- return (0);
+ return 0;
else {
for (ptr = el->el_line.cursor - 1;
ptr >= el->el_line.buffer && *ptr != '\n';
ptr--)
continue;
- return (el->el_line.cursor - ptr - 1);
+ return (int)(el->el_line.cursor - ptr - 1);
}
}
+
+protected int
+ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
+{
+ el->el_chared.c_resizefun = f;
+ el->el_chared.c_resizearg = a;
+ return 0;
+}
diff --git a/cmd-line-utils/libedit/chared.h b/cmd-line-utils/libedit/chared.h
index fa8f5a58d83..176475ac8f0 100644
--- a/cmd-line-utils/libedit/chared.h
+++ b/cmd-line-utils/libedit/chared.h
@@ -1,4 +1,4 @@
-/* $NetBSD: chared.h,v 1.17 2006/03/06 21:11:56 christos Exp $ */
+/* $NetBSD: chared.h,v 1.21 2010/08/28 15:44:59 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -63,25 +63,25 @@
typedef struct c_macro_t {
int level;
int offset;
- char **macro;
+ Char **macro;
} c_macro_t;
/*
* Undo information for vi - no undo in emacs (yet)
*/
typedef struct c_undo_t {
- int len; /* length of saved line */
+ ssize_t len; /* length of saved line */
int cursor; /* position of saved cursor */
- char *buf; /* full saved text */
+ Char *buf; /* full saved text */
} c_undo_t;
/* redo for vi */
typedef struct c_redo_t {
- char *buf; /* redo insert key sequence */
- char *pos;
- char *lim;
+ Char *buf; /* redo insert key sequence */
+ Char *pos;
+ Char *lim;
el_action_t cmd; /* command to redo */
- char ch; /* char that invoked it */
+ Char ch; /* char that invoked it */
int count;
int action; /* from cv_action() */
} c_redo_t;
@@ -91,18 +91,20 @@ typedef struct c_redo_t {
*/
typedef struct c_vcmd_t {
int action;
- char *pos;
+ Char *pos;
} c_vcmd_t;
/*
* Kill buffer for emacs
*/
typedef struct c_kill_t {
- char *buf;
- char *last;
- char *mark;
+ Char *buf;
+ Char *last;
+ Char *mark;
} c_kill_t;
+typedef void (*el_zfunc_t)(EditLine *, void *);
+
/*
* Note that we use both data structures because the user can bind
* commands from both editors!
@@ -113,13 +115,14 @@ typedef struct el_chared_t {
c_redo_t c_redo;
c_vcmd_t c_vcmd;
c_macro_t c_macro;
+ el_zfunc_t c_resizefun;
+ void * c_resizearg;
} el_chared_t;
#define STRQQ "\"\""
#define isglob(a) (strchr("*[]?", (a)) != NULL)
-#define isword(a) (el_isprint(a))
#define NOP 0x00
#define DELETE 0x01
@@ -140,27 +143,28 @@ typedef struct el_chared_t {
#include "fcns.h"
-protected int cv__isword(int);
-protected int cv__isWord(int);
+protected int cv__isword(Int);
+protected int cv__isWord(Int);
protected void cv_delfini(EditLine *);
-protected char *cv__endword(char *, char *, int, int (*)(int));
-protected int ce__isword(int);
+protected Char *cv__endword(Char *, Char *, int, int (*)(Int));
+protected int ce__isword(Int);
protected void cv_undo(EditLine *);
-protected void cv_yank(EditLine *, const char *, int);
-protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int));
-protected char *cv_prev_word(char *, char *, int, int (*)(int));
-protected char *c__next_word(char *, char *, int, int (*)(int));
-protected char *c__prev_word(char *, char *, int, int (*)(int));
+protected void cv_yank(EditLine *, const Char *, int);
+protected Char *cv_next_word(EditLine*, Char *, Char *, int, int (*)(Int));
+protected Char *cv_prev_word(Char *, Char *, int, int (*)(Int));
+protected Char *c__next_word(Char *, Char *, int, int (*)(Int));
+protected Char *c__prev_word(Char *, Char *, int, int (*)(Int));
protected void c_insert(EditLine *, int);
protected void c_delbefore(EditLine *, int);
protected void c_delbefore1(EditLine *);
protected void c_delafter(EditLine *, int);
protected void c_delafter1(EditLine *);
-protected int c_gets(EditLine *, char *, const char *);
+protected int c_gets(EditLine *, Char *, const Char *);
protected int c_hpos(EditLine *);
protected int ch_init(EditLine *);
protected void ch_reset(EditLine *, int);
+protected int ch_resizefun(EditLine *, el_zfunc_t, void *);
protected int ch_enlargebufs(EditLine *, size_t);
protected void ch_end(EditLine *);
diff --git a/cmd-line-utils/libedit/chartype.c b/cmd-line-utils/libedit/chartype.c
new file mode 100644
index 00000000000..b70aebeec46
--- /dev/null
+++ b/cmd-line-utils/libedit/chartype.c
@@ -0,0 +1,361 @@
+/* $NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $ */
+
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * 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 reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. 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 THE FOUNDATION 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.
+ */
+
+/*
+ * chartype.c: character classification and meta information
+ */
+#include "config.h"
+#if !defined(lint) && !defined(SCCSID)
+#endif /* not lint && not SCCSID */
+#include "el.h"
+#include <stdlib.h>
+
+#define CT_BUFSIZ ((size_t)1024)
+
+#ifdef WIDECHAR
+protected void
+ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize)
+{
+ void *p;
+ if (mincsize > conv->csize) {
+ conv->csize = mincsize;
+ p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff));
+ if (p == NULL) {
+ conv->csize = 0;
+ el_free(conv->cbuff);
+ conv->cbuff = NULL;
+ } else
+ conv->cbuff = p;
+ }
+
+ if (minwsize > conv->wsize) {
+ conv->wsize = minwsize;
+ p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff));
+ if (p == NULL) {
+ conv->wsize = 0;
+ el_free(conv->wbuff);
+ conv->wbuff = NULL;
+ } else
+ conv->wbuff = p;
+ }
+}
+
+
+public char *
+ct_encode_string(const Char *s, ct_buffer_t *conv)
+{
+ char *dst;
+ ssize_t used = 0;
+ mbstate_t state;
+
+ memset(&state, 0, sizeof(mbstate_t));
+
+ if (!s)
+ return NULL;
+ if (!conv->cbuff)
+ ct_conv_buff_resize(conv, CT_BUFSIZ, (size_t)0);
+ if (!conv->cbuff)
+ return NULL;
+
+ dst = conv->cbuff;
+ while (*s) {
+ used = (ssize_t)(conv->csize - (size_t)(dst - conv->cbuff));
+ if (used < 5) {
+ used = dst - conv->cbuff;
+ ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ,
+ (size_t)0);
+ if (!conv->cbuff)
+ return NULL;
+ dst = conv->cbuff + used;
+ }
+ used = ct_encode_char(dst, (size_t)5, *s, &state);
+ if (used == -1) /* failed to encode, need more buffer space */
+ abort();
+ ++s;
+ dst += used;
+ }
+ *dst = '\0';
+ return conv->cbuff;
+}
+
+public Char *
+ct_decode_string(const char *s, ct_buffer_t *conv)
+{
+ size_t len = 0;
+
+ if (!s)
+ return NULL;
+ if (!conv->wbuff)
+ ct_conv_buff_resize(conv, (size_t)0, CT_BUFSIZ);
+ if (!conv->wbuff)
+ return NULL;
+
+ len = ct_mbstowcs(NULL, s, (size_t)0);
+ if (len == (size_t)-1)
+ return NULL;
+ if (len > conv->wsize)
+ ct_conv_buff_resize(conv, (size_t)0, len + 1);
+ if (!conv->wbuff)
+ return NULL;
+ ct_mbstowcs(conv->wbuff, s, conv->wsize);
+ return conv->wbuff;
+}
+
+
+protected Char **
+ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
+{
+ size_t bufspace;
+ int i;
+ Char *p;
+ Char **wargv;
+ ssize_t bytes;
+ mbstate_t state;
+
+ /* Make sure we have enough space in the conversion buffer to store all
+ * the argv strings. */
+ for (i = 0, bufspace = 0; i < argc; ++i)
+ bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
+ ct_conv_buff_resize(conv, (size_t)0, bufspace);
+ if (!conv->wsize)
+ return NULL;
+
+ wargv = el_malloc((size_t)argc * sizeof(*wargv));
+
+ for (i = 0, p = conv->wbuff; i < argc; ++i) {
+ if (!argv[i]) { /* don't pass null pointers to mbsrtowcs */
+ wargv[i] = NULL;
+ continue;
+ } else {
+ wargv[i] = p;
+ memset(&state, 0, sizeof(mbstate_t));
+ bytes = (ssize_t)mbsrtowcs(p, argv + i, bufspace, &state);
+ }
+ if (bytes == -1) {
+ el_free(wargv);
+ return NULL;
+ } else
+ bytes++; /* include '\0' in the count */
+ bufspace -= (size_t)bytes;
+ p += bytes;
+ }
+
+ return wargv;
+}
+
+
+protected size_t
+ct_enc_width(Char c)
+{
+ /* UTF-8 encoding specific values */
+ if (c < 0x80)
+ return 1;
+ else if (c < 0x0800)
+ return 2;
+ else if (c < 0x10000)
+ return 3;
+ else if (c < 0x110000)
+ return 4;
+ else
+ return 0; /* not a valid codepoint */
+}
+
+protected ssize_t
+ct_encode_char(char *dst, size_t len, Char c, mbstate_t *state)
+{
+ ssize_t l = 0;
+
+ if (len < ct_enc_width(c))
+ return -1;
+
+ l = wcrtomb(dst, c, state);
+
+ if (l < 0) {
+ memset (state, 0, sizeof (mbstate_t));
+ l = 0;
+ }
+ return l;
+}
+#endif
+
+protected const Char *
+ct_visual_string(const Char *s)
+{
+ static Char *buff = NULL;
+ static size_t buffsize = 0;
+ void *p;
+ Char *dst;
+ ssize_t used = 0;
+
+ if (!s)
+ return NULL;
+ if (!buff) {
+ buffsize = CT_BUFSIZ;
+ buff = el_malloc(buffsize * sizeof(*buff));
+ }
+ dst = buff;
+ while (*s) {
+ used = ct_visual_char(dst, buffsize - (size_t)(dst - buff), *s);
+ if (used == -1) { /* failed to encode, need more buffer space */
+ used = dst - buff;
+ buffsize += CT_BUFSIZ;
+ p = el_realloc(buff, buffsize * sizeof(*buff));
+ if (p == NULL)
+ goto out;
+ buff = p;
+ dst = buff + used;
+ /* don't increment s here - we want to retry it! */
+ }
+ else
+ ++s;
+ dst += used;
+ }
+ if (dst >= (buff + buffsize)) { /* sigh */
+ buffsize += 1;
+ p = el_realloc(buff, buffsize * sizeof(*buff));
+ if (p == NULL)
+ goto out;
+ buff = p;
+ dst = buff + buffsize - 1;
+ }
+ *dst = 0;
+ return buff;
+out:
+ el_free(buff);
+ buffsize = 0;
+ return NULL;
+}
+
+
+protected int
+ct_visual_width(Char c)
+{
+ int t = ct_chr_class(c);
+ switch (t) {
+ case CHTYPE_ASCIICTL:
+ return 2; /* ^@ ^? etc. */
+ case CHTYPE_TAB:
+ return 1; /* Hmm, this really need to be handled outside! */
+ case CHTYPE_NL:
+ return 0; /* Should this be 1 instead? */
+#ifdef WIDECHAR
+ case CHTYPE_PRINT:
+ return wcwidth(c);
+ case CHTYPE_NONPRINT:
+ if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
+ return 8; /* \U+12345 */
+ else
+ return 7; /* \U+1234 */
+#else
+ case CHTYPE_PRINT:
+ return 1;
+ case CHTYPE_NONPRINT:
+ return 4; /* \123 */
+#endif
+ default:
+ return 0; /* should not happen */
+ }
+}
+
+
+protected ssize_t
+ct_visual_char(Char *dst, size_t len, Char c)
+{
+ int t = ct_chr_class(c);
+ switch (t) {
+ case CHTYPE_TAB:
+ case CHTYPE_NL:
+ case CHTYPE_ASCIICTL:
+ if (len < 2)
+ return -1; /* insufficient space */
+ *dst++ = '^';
+ if (c == '\177')
+ *dst = '?'; /* DEL -> ^? */
+ else
+ *dst = c | 0100; /* uncontrolify it */
+ return 2;
+ case CHTYPE_PRINT:
+ if (len < 1)
+ return -1; /* insufficient space */
+ *dst = c;
+ return 1;
+ case CHTYPE_NONPRINT:
+ /* we only use single-width glyphs for display,
+ * so this is right */
+ if ((ssize_t)len < ct_visual_width(c))
+ return -1; /* insufficient space */
+#ifdef WIDECHAR
+ *dst++ = '\\';
+ *dst++ = 'U';
+ *dst++ = '+';
+#define tohexdigit(v) "0123456789ABCDEF"[v]
+ if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
+ *dst++ = tohexdigit(((unsigned int) c >> 16) & 0xf);
+ *dst++ = tohexdigit(((unsigned int) c >> 12) & 0xf);
+ *dst++ = tohexdigit(((unsigned int) c >> 8) & 0xf);
+ *dst++ = tohexdigit(((unsigned int) c >> 4) & 0xf);
+ *dst = tohexdigit(((unsigned int) c ) & 0xf);
+ return c > 0xffff ? 8 : 7;
+#else
+ *dst++ = '\\';
+#define tooctaldigit(v) ((v) + '0')
+ *dst++ = tooctaldigit(((unsigned int) c >> 6) & 0x7);
+ *dst++ = tooctaldigit(((unsigned int) c >> 3) & 0x7);
+ *dst++ = tooctaldigit(((unsigned int) c ) & 0x7);
+#endif
+ /*FALLTHROUGH*/
+ /* these two should be handled outside this function */
+ default: /* we should never hit the default */
+ return 0;
+ }
+}
+
+
+
+
+protected int
+ct_chr_class(Char c)
+{
+ if (c == '\t')
+ return CHTYPE_TAB;
+ else if (c == '\n')
+ return CHTYPE_NL;
+ else if (IsASCII(c) && Iscntrl(c))
+ return CHTYPE_ASCIICTL;
+ else if (Isprint(c))
+ return CHTYPE_PRINT;
+ else
+ return CHTYPE_NONPRINT;
+}
diff --git a/cmd-line-utils/libedit/chartype.h b/cmd-line-utils/libedit/chartype.h
new file mode 100644
index 00000000000..678d13683be
--- /dev/null
+++ b/cmd-line-utils/libedit/chartype.h
@@ -0,0 +1,252 @@
+/* $NetBSD: chartype.h,v 1.8 2011/07/29 23:44:44 christos Exp $ */
+
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * 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 reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. 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 THE FOUNDATION 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 _h_chartype_f
+#define _h_chartype_f
+
+
+
+#ifdef WIDECHAR
+
+/* Ideally we should also test the value of the define to see if it
+ * supports non-BMP code points without requiring UTF-16, but nothing
+ * seems to actually advertise this properly, despite Unicode 3.1 having
+ * been around since 2001... */
+
+/* XXXMYSQL : Added FreeBSD to bypass this check.
+ TODO : Verify if FreeBSD stores ISO 10646 in wchar_t. */
+#if !defined(__NetBSD__) && !defined(__sun) \
+ && !(defined(__APPLE__) && defined(__MACH__)) \
+ && !defined(__FreeBSD__)
+#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
+ * funky encoding that could break us in weird and wonderful ways. */
+ #error wchar_t must store ISO 10646 characters
+#endif
+#endif
+
+/* Oh for a <uchar.h> with char32_t and __STDC_UTF_32__ in it...
+ * ref: ISO/IEC DTR 19769
+ */
+#if WCHAR_MAX < INT32_MAX
+#warning Build environment does not support non-BMP characters
+#endif
+
+#ifndef HAVE_WCSDUP
+wchar_t *wcsdup(const wchar_t *s);
+#endif
+
+#define ct_wctomb wctomb
+#define ct_wctomb_reset wctomb(0,0)
+#define ct_wcstombs wcstombs
+#define ct_mbstowcs mbstowcs
+
+#define Char wchar_t
+#define Int wint_t
+#define FUN(prefix,rest) prefix ## _w ## rest
+#define FUNW(type) type ## _w
+#define TYPE(type) type ## W
+#define FSTR "%ls"
+#define STR(x) L ## x
+#define UC(c) c
+#define Isalpha(x) iswalpha(x)
+#define Isalnum(x) iswalnum(x)
+#define Isgraph(x) iswgraph(x)
+#define Isspace(x) iswspace(x)
+#define Isdigit(x) iswdigit(x)
+#define Iscntrl(x) iswcntrl(x)
+#define Isprint(x) iswprint(x)
+
+#define Isupper(x) iswupper(x)
+#define Islower(x) iswlower(x)
+#define Toupper(x) towupper(x)
+#define Tolower(x) towlower(x)
+
+#define IsASCII(x) (x < 0x100)
+
+#define Strlen(x) wcslen(x)
+#define Strchr(s,c) wcschr(s,c)
+#define Strrchr(s,c) wcsrchr(s,c)
+#define Strstr(s,v) wcsstr(s,v)
+#define Strdup(x) wcsdup(x)
+#define Strcpy(d,s) wcscpy(d,s)
+#define Strncpy(d,s,n) wcsncpy(d,s,n)
+#define Strncat(d,s,n) wcsncat(d,s,n)
+
+#define Strcmp(s,v) wcscmp(s,v)
+#define Strncmp(s,v,n) wcsncmp(s,v,n)
+#define Strcspn(s,r) wcscspn(s,r)
+
+#define Strtol(p,e,b) wcstol(p,e,b)
+
+#define Width(c) wcwidth(c)
+
+#else /* NARROW */
+
+#define ct_mbtowc error
+#define ct_mbtowc_reset
+#define ct_wctomb error
+#define ct_wctomb_reset
+#define ct_wcstombs(a, b, c) (strncpy(a, b, c), strlen(a))
+#define ct_mbstowcs(a, b, c) (strncpy(a, b, c), strlen(a))
+
+#define Char char
+#define Int int
+#define FUN(prefix,rest) prefix ## _ ## rest
+#define FUNW(type) type
+#define TYPE(type) type
+#define FSTR "%s"
+#define STR(x) x
+#define UC(c) (unsigned char)(c)
+
+#define Isalpha(x) isalpha((unsigned char)x)
+#define Isalnum(x) isalnum((unsigned char)x)
+#define Isgraph(x) isgraph((unsigned char)x)
+#define Isspace(x) isspace((unsigned char)x)
+#define Isdigit(x) isdigit((unsigned char)x)
+#define Iscntrl(x) iscntrl((unsigned char)x)
+#define Isprint(x) isprint((unsigned char)x)
+
+#define Isupper(x) isupper((unsigned char)x)
+#define Islower(x) islower((unsigned char)x)
+#define Toupper(x) toupper((unsigned char)x)
+#define Tolower(x) tolower((unsigned char)x)
+
+#define IsASCII(x) isascii((unsigned char)x)
+
+#define Strlen(x) strlen(x)
+#define Strchr(s,c) strchr(s,c)
+#define Strrchr(s,c) strrchr(s,c)
+#define Strstr(s,v) strstr(s,v)
+#define Strdup(x) strdup(x)
+#define Strcpy(d,s) strcpy(d,s)
+#define Strncpy(d,s,n) strncpy(d,s,n)
+#define Strncat(d,s,n) strncat(d,s,n)
+
+#define Strcmp(s,v) strcmp(s,v)
+#define Strncmp(s,v,n) strncmp(s,v,n)
+#define Strcspn(s,r) strcspn(s,r)
+
+#define Strtol(p,e,b) strtol(p,e,b)
+
+#define Width(c) 1
+
+#endif
+
+
+#ifdef WIDECHAR
+/*
+ * Conversion buffer
+ */
+typedef struct ct_buffer_t {
+ char *cbuff;
+ size_t csize;
+ Char *wbuff;
+ size_t wsize;
+} ct_buffer_t;
+
+#define ct_encode_string __ct_encode_string
+/* Encode a wide-character string and return the UTF-8 encoded result. */
+public char *ct_encode_string(const Char *, ct_buffer_t *);
+
+#define ct_decode_string __ct_decode_string
+/* Decode a (multi)?byte string and return the wide-character string result. */
+public Char *ct_decode_string(const char *, ct_buffer_t *);
+
+/* Decode a (multi)?byte argv string array.
+ * The pointer returned must be free()d when done. */
+protected Char **ct_decode_argv(int, const char *[], ct_buffer_t *);
+
+/* Resizes the conversion buffer(s) if needed. */
+protected void ct_conv_buff_resize(ct_buffer_t *, size_t, size_t);
+protected ssize_t ct_encode_char(char *, size_t, Char, mbstate_t *);
+protected size_t ct_enc_width(Char);
+
+#define ct_free_argv(s) el_free(s)
+
+#else
+#define ct_encode_string(s, b) (s)
+#define ct_decode_string(s, b) (s)
+#define ct_decode_argv(l, s, b) (s)
+#define ct_conv_buff_resize(b, os, ns)
+#define ct_encode_char(d, l, s, ps) (*d = s, 1)
+#define ct_free_argv(s)
+#endif
+
+#ifndef NARROWCHAR
+/* Encode a characted into the destination buffer, provided there is sufficent
+ * buffer space available. Returns the number of bytes used up (zero if the
+ * character cannot be encoded, -1 if there was not enough space available). */
+
+/* The maximum buffer size to hold the most unwieldly visual representation,
+ * in this case \U+nnnnn. */
+#define VISUAL_WIDTH_MAX ((size_t)8)
+
+/* The terminal is thought of in terms of X columns by Y lines. In the cases
+ * where a wide character takes up more than one column, the adjacent
+ * occupied column entries will contain this faux character. */
+#define MB_FILL_CHAR ((Char)-1)
+
+/* Visual width of character c, taking into account ^? , \0177 and \U+nnnnn
+ * style visual expansions. */
+protected int ct_visual_width(Char);
+
+/* Turn the given character into the appropriate visual format, matching
+ * the width given by ct_visual_width(). Returns the number of characters used
+ * up, or -1 if insufficient space. Buffer length is in count of Char's. */
+protected ssize_t ct_visual_char(Char *, size_t, Char);
+
+/* Convert the given string into visual format, using the ct_visual_char()
+ * function. Uses a static buffer, so not threadsafe. */
+protected const Char *ct_visual_string(const Char *);
+
+
+/* printable character, use ct_visual_width() to find out display width */
+#define CHTYPE_PRINT ( 0)
+/* control character found inside the ASCII portion of the charset */
+#define CHTYPE_ASCIICTL (-1)
+/* a \t */
+#define CHTYPE_TAB (-2)
+/* a \n */
+#define CHTYPE_NL (-3)
+/* non-printable character */
+#define CHTYPE_NONPRINT (-4)
+/* classification of character c, as one of the above defines */
+protected int ct_chr_class(Char c);
+#endif
+
+
+#endif /* _chartype_f */
diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c
index ba5890fa606..c0512061e6f 100644
--- a/cmd-line-utils/libedit/common.c
+++ b/cmd-line-utils/libedit/common.c
@@ -1,4 +1,4 @@
-/* $NetBSD: common.c,v 1.21 2008/09/30 08:37:42 aymeric Exp $ */
+/* $NetBSD: common.c,v 1.28 2011/07/29 20:58:07 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -51,12 +51,12 @@ static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
*/
protected el_action_t
/*ARGSUSED*/
-ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
+ed_end_of_file(EditLine *el, Int c __attribute__((__unused__)))
{
re_goto_bottom(el);
*el->el_line.lastchar = '\0';
- return (CC_EOF);
+ return CC_EOF;
}
@@ -65,12 +65,12 @@ ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
* Insert a character [bound to all insert keys]
*/
protected el_action_t
-ed_insert(EditLine *el, int c)
+ed_insert(EditLine *el, Int c)
{
int count = el->el_state.argument;
if (c == '\0')
- return (CC_ERROR);
+ return CC_ERROR;
if (el->el_line.lastchar + el->el_state.argument >=
el->el_line.limit) {
@@ -98,7 +98,7 @@ ed_insert(EditLine *el, int c)
if (el->el_state.inputmode == MODE_REPLACE_1)
return vi_command_mode(el, 0);
- return (CC_NORM);
+ return CC_NORM;
}
@@ -108,12 +108,12 @@ ed_insert(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
+ed_delete_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
- char *cp, *p, *kp;
+ Char *cp, *p, *kp;
if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
+ return CC_ERROR;
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
el->el_state.argument, ce__isword);
@@ -122,11 +122,11 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
*kp++ = *p;
el->el_chared.c_kill.last = kp;
- c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */
+ c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */
el->el_line.cursor = cp;
if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer; /* bounds check */
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -136,9 +136,9 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
+ed_delete_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
-#ifdef notdef /* XXX */
+#ifdef DEBUG_EDIT
#define EL el->el_line
(void) fprintf(el->el_errlfile,
"\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n",
@@ -151,24 +151,24 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
if (el->el_line.cursor == el->el_line.buffer) {
/* if I'm also at the beginning */
#ifdef KSHVI
- return (CC_ERROR);
+ return CC_ERROR;
#else
/* then do an EOF */
- term_writechar(el, c);
- return (CC_EOF);
+ terminal_writec(el, c);
+ return CC_EOF;
#endif
} else {
#ifdef KSHVI
el->el_line.cursor--;
#else
- return (CC_ERROR);
+ return CC_ERROR;
#endif
}
} else {
if (el->el_line.cursor != el->el_line.buffer)
el->el_line.cursor--;
else
- return (CC_ERROR);
+ return CC_ERROR;
}
}
c_delafter(el, el->el_state.argument); /* delete after dot */
@@ -176,7 +176,7 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
el->el_line.cursor > el->el_line.buffer)
/* bounds check */
el->el_line.cursor = el->el_line.lastchar - 1;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -186,9 +186,9 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
+ed_kill_line(EditLine *el, Int c __attribute__((__unused__)))
{
- char *kp, *cp;
+ Char *kp, *cp;
cp = el->el_line.cursor;
kp = el->el_chared.c_kill.buf;
@@ -197,7 +197,7 @@ ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
el->el_chared.c_kill.last = kp;
/* zap! -- delete to end */
el->el_line.lastchar = el->el_line.cursor;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -207,20 +207,20 @@ ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
+ed_move_to_end(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.lastchar;
if (el->el_map.type == MAP_VI) {
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
#ifdef VI_MOVE
el->el_line.cursor--;
#endif
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -230,21 +230,21 @@ ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
+ed_move_to_beg(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
if (el->el_map.type == MAP_VI) {
/* We want FIRST non space character */
- while (isspace((unsigned char) *el->el_line.cursor))
+ while (Isspace(*el->el_line.cursor))
el->el_line.cursor++;
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -253,12 +253,12 @@ ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
* [^T] [^T]
*/
protected el_action_t
-ed_transpose_chars(EditLine *el, int c)
+ed_transpose_chars(EditLine *el, Int c)
{
if (el->el_line.cursor < el->el_line.lastchar) {
if (el->el_line.lastchar <= &el->el_line.buffer[1])
- return (CC_ERROR);
+ return CC_ERROR;
else
el->el_line.cursor++;
}
@@ -267,9 +267,9 @@ ed_transpose_chars(EditLine *el, int c)
c = el->el_line.cursor[-2];
el->el_line.cursor[-2] = el->el_line.cursor[-1];
el->el_line.cursor[-1] = c;
- return (CC_REFRESH);
+ return CC_REFRESH;
} else
- return (CC_ERROR);
+ return CC_ERROR;
}
@@ -279,15 +279,15 @@ ed_transpose_chars(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-ed_next_char(EditLine *el, int c __attribute__((__unused__)))
+ed_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
- char *lim = el->el_line.lastchar;
+ Char *lim = el->el_line.lastchar;
if (el->el_line.cursor >= lim ||
(el->el_line.cursor == lim - 1 &&
el->el_map.type == MAP_VI &&
el->el_chared.c_vcmd.action == NOP))
- return (CC_ERROR);
+ return CC_ERROR;
el->el_line.cursor += el->el_state.argument;
if (el->el_line.cursor > lim)
@@ -296,9 +296,9 @@ ed_next_char(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -308,11 +308,11 @@ ed_next_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
+ed_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_line.cursor = c__prev_word(el->el_line.cursor,
el->el_line.buffer,
@@ -322,9 +322,9 @@ ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -334,7 +334,7 @@ ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
+ed_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor > el->el_line.buffer) {
@@ -345,11 +345,11 @@ ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
} else
- return (CC_ERROR);
+ return CC_ERROR;
}
@@ -358,19 +358,19 @@ ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
* [^V] [^V]
*/
protected el_action_t
-ed_quoted_insert(EditLine *el, int c)
+ed_quoted_insert(EditLine *el, Int c)
{
int num;
- char tc;
+ Char tc;
tty_quotemode(el);
- num = el_getc(el, &tc);
- c = (unsigned char) tc;
+ num = FUN(el,getc)(el, &tc);
+ c = tc;
tty_noquotemode(el);
if (num == 1)
- return (ed_insert(el, c));
+ return ed_insert(el, c);
else
- return (ed_end_of_file(el, 0));
+ return ed_end_of_file(el, 0);
}
@@ -378,11 +378,11 @@ ed_quoted_insert(EditLine *el, int c)
* Adds to argument or enters a digit
*/
protected el_action_t
-ed_digit(EditLine *el, int c)
+ed_digit(EditLine *el, Int c)
{
- if (!isdigit(c))
- return (CC_ERROR);
+ if (!Isdigit(c))
+ return CC_ERROR;
if (el->el_state.doingarg) {
/* if doing an arg, add this in... */
@@ -390,11 +390,11 @@ ed_digit(EditLine *el, int c)
el->el_state.argument = c - '0';
else {
if (el->el_state.argument > 1000000)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_state.argument =
(el->el_state.argument * 10) + (c - '0');
}
- return (CC_ARGHACK);
+ return CC_ARGHACK;
}
return ed_insert(el, c);
@@ -406,22 +406,22 @@ ed_digit(EditLine *el, int c)
* For ESC-n
*/
protected el_action_t
-ed_argument_digit(EditLine *el, int c)
+ed_argument_digit(EditLine *el, Int c)
{
- if (!isdigit(c))
- return (CC_ERROR);
+ if (!Isdigit(c))
+ return CC_ERROR;
if (el->el_state.doingarg) {
if (el->el_state.argument > 1000000)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_state.argument = (el->el_state.argument * 10) +
(c - '0');
} else { /* else starting an argument */
el->el_state.argument = c - '0';
el->el_state.doingarg = 1;
}
- return (CC_ARGHACK);
+ return CC_ARGHACK;
}
@@ -432,10 +432,10 @@ ed_argument_digit(EditLine *el, int c)
protected el_action_t
/*ARGSUSED*/
ed_unassigned(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_ERROR);
+ return CC_ERROR;
}
@@ -450,10 +450,10 @@ ed_unassigned(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_sigint(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_NORM);
+ return CC_NORM;
}
@@ -464,10 +464,10 @@ ed_tty_sigint(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_NORM);
+ return CC_NORM;
}
@@ -478,10 +478,10 @@ ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_NORM);
+ return CC_NORM;
}
@@ -492,10 +492,10 @@ ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_NORM);
+ return CC_NORM;
}
@@ -506,10 +506,10 @@ ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_NORM);
+ return CC_NORM;
}
@@ -520,10 +520,10 @@ ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_NORM);
+ return CC_NORM;
}
@@ -534,10 +534,10 @@ ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_start_output(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_NORM);
+ return CC_NORM;
}
@@ -547,13 +547,13 @@ ed_tty_start_output(EditLine *el __attribute__((__unused__)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_newline(EditLine *el, int c __attribute__((__unused__)))
+ed_newline(EditLine *el, Int c __attribute__((__unused__)))
{
re_goto_bottom(el);
*el->el_line.lastchar++ = '\n';
*el->el_line.lastchar = '\0';
- return (CC_NEWLINE);
+ return CC_NEWLINE;
}
@@ -563,17 +563,17 @@ ed_newline(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
+ed_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
- return (CC_ERROR);
+ return CC_ERROR;
c_delbefore(el, el->el_state.argument);
el->el_line.cursor -= el->el_state.argument;
if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -583,12 +583,12 @@ ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
+ed_clear_screen(EditLine *el, Int c __attribute__((__unused__)))
{
- term_clear_screen(el); /* clear the whole real screen */
+ terminal_clear_screen(el); /* clear the whole real screen */
re_clear_display(el); /* reset everything */
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -599,10 +599,10 @@ ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
protected el_action_t
/*ARGSUSED*/
ed_redisplay(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_REDISPLAY);
+ return CC_REDISPLAY;
}
@@ -612,11 +612,11 @@ ed_redisplay(EditLine *el __attribute__((__unused__)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_start_over(EditLine *el, int c __attribute__((__unused__)))
+ed_start_over(EditLine *el, Int c __attribute__((__unused__)))
{
ch_reset(el, 0);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -627,10 +627,10 @@ ed_start_over(EditLine *el, int c __attribute__((__unused__)))
protected el_action_t
/*ARGSUSED*/
ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
- return (CC_NORM);
+ return CC_NORM;
}
@@ -640,7 +640,7 @@ ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
*/
protected el_action_t
/*ARGSUSED*/
-ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
+ed_prev_history(EditLine *el, Int c __attribute__((__unused__)))
{
char beep = 0;
int sv_event = el->el_history.eventno;
@@ -650,7 +650,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
if (el->el_history.eventno == 0) { /* save the current buffer
* away */
- (void) strncpy(el->el_history.buf, el->el_line.buffer,
+ (void) Strncpy(el->el_history.buf, el->el_line.buffer,
EL_BUFSIZ);
el->el_history.last = el->el_history.buf +
(el->el_line.lastchar - el->el_line.buffer);
@@ -660,7 +660,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
if (hist_get(el) == CC_ERROR) {
if (el->el_map.type == MAP_VI) {
el->el_history.eventno = sv_event;
- return CC_ERROR;
+
}
beep = 1;
/* el->el_history.eventno was fixed by first call */
@@ -678,7 +678,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_next_history(EditLine *el, int c __attribute__((__unused__)))
+ed_next_history(EditLine *el, Int c __attribute__((__unused__)))
{
el_action_t beep = CC_REFRESH, rval;
@@ -705,9 +705,9 @@ ed_next_history(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
+ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__)))
{
- const char *hp;
+ const Char *hp;
int h;
bool_t found = 0;
@@ -720,20 +720,20 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
"e_prev_search_hist(): eventno < 0;\n");
#endif
el->el_history.eventno = 0;
- return (CC_ERROR);
+ return CC_ERROR;
}
if (el->el_history.eventno == 0) {
- (void) strncpy(el->el_history.buf, el->el_line.buffer,
+ (void) Strncpy(el->el_history.buf, el->el_line.buffer,
EL_BUFSIZ);
el->el_history.last = el->el_history.buf +
(el->el_line.lastchar - el->el_line.buffer);
}
if (el->el_history.ref == NULL)
- return (CC_ERROR);
+ return CC_ERROR;
hp = HIST_FIRST(el);
if (hp == NULL)
- return (CC_ERROR);
+ return CC_ERROR;
c_setpat(el); /* Set search pattern !! */
@@ -744,7 +744,7 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
- if ((strncmp(hp, el->el_line.buffer, (size_t)
+ if ((Strncmp(hp, el->el_line.buffer, (size_t)
(el->el_line.lastchar - el->el_line.buffer)) ||
hp[el->el_line.lastchar - el->el_line.buffer]) &&
c_hmatch(el, hp)) {
@@ -759,11 +759,11 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "not found\n");
#endif
- return (CC_ERROR);
+ return CC_ERROR;
}
el->el_history.eventno = h;
- return (hist_get(el));
+ return hist_get(el);
}
@@ -773,9 +773,9 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
+ed_search_next_history(EditLine *el, Int c __attribute__((__unused__)))
{
- const char *hp;
+ const Char *hp;
int h;
bool_t found = 0;
@@ -784,14 +784,14 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
*el->el_line.lastchar = '\0'; /* just in case */
if (el->el_history.eventno == 0)
- return (CC_ERROR);
+ return CC_ERROR;
if (el->el_history.ref == NULL)
- return (CC_ERROR);
+ return CC_ERROR;
hp = HIST_FIRST(el);
if (hp == NULL)
- return (CC_ERROR);
+ return CC_ERROR;
c_setpat(el); /* Set search pattern !! */
@@ -799,7 +799,7 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
- if ((strncmp(hp, el->el_line.buffer, (size_t)
+ if ((Strncmp(hp, el->el_line.buffer, (size_t)
(el->el_line.lastchar - el->el_line.buffer)) ||
hp[el->el_line.lastchar - el->el_line.buffer]) &&
c_hmatch(el, hp))
@@ -812,12 +812,12 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "not found\n");
#endif
- return (CC_ERROR);
+ return CC_ERROR;
}
}
el->el_history.eventno = found;
- return (hist_get(el));
+ return hist_get(el);
}
@@ -827,9 +827,9 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
+ed_prev_line(EditLine *el, Int c __attribute__((__unused__)))
{
- char *ptr;
+ Char *ptr;
int nchars = c_hpos(el);
/*
@@ -843,7 +843,7 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
break;
if (el->el_state.argument > 0)
- return (CC_ERROR);
+ return CC_ERROR;
/*
* Move to the beginning of the line
@@ -860,7 +860,7 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
continue;
el->el_line.cursor = ptr;
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -870,9 +870,9 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_next_line(EditLine *el, int c __attribute__((__unused__)))
+ed_next_line(EditLine *el, Int c __attribute__((__unused__)))
{
- char *ptr;
+ Char *ptr;
int nchars = c_hpos(el);
/*
@@ -883,7 +883,7 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__)))
break;
if (el->el_state.argument > 0)
- return (CC_ERROR);
+ return CC_ERROR;
/*
* Move to the character requested
@@ -894,7 +894,7 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__)))
continue;
el->el_line.cursor = ptr;
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -904,16 +904,16 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-ed_command(EditLine *el, int c __attribute__((__unused__)))
+ed_command(EditLine *el, Int c __attribute__((__unused__)))
{
- char tmpbuf[EL_BUFSIZ];
+ Char tmpbuf[EL_BUFSIZ];
int tmplen;
- tmplen = c_gets(el, tmpbuf, "\n: ");
- term__putc(el, '\n');
+ tmplen = c_gets(el, tmpbuf, STR("\n: "));
+ terminal__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
- term_beep(el);
+ terminal_beep(el);
el->el_map.current = el->el_map.key;
re_clear_display(el);
diff --git a/cmd-line-utils/libedit/config.h b/cmd-line-utils/libedit/config.h
index 2c3989ee316..c06d5e28a0a 100644
--- a/cmd-line-utils/libedit/config.h
+++ b/cmd-line-utils/libedit/config.h
@@ -1,2 +1,5 @@
#include "my_config.h"
#include "sys.h"
+#ifndef NARROW_WRAPPER
+#define WIDECHAR
+#endif
diff --git a/cmd-line-utils/libedit/el.c b/cmd-line-utils/libedit/el.c
index c7f8386773d..c7f4f81ec93 100644
--- a/cmd-line-utils/libedit/el.c
+++ b/cmd-line-utils/libedit/el.c
@@ -1,4 +1,4 @@
-/* $NetBSD: el.c,v 1.47 2009/01/18 12:17:24 lukem Exp $ */
+/* $NetBSD: el.c,v 1.68 2011/07/29 15:16:33 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -48,6 +48,9 @@ static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <ctype.h>
+#include <locale.h>
+#include <langinfo.h>
#include "el.h"
/* el_init():
@@ -56,11 +59,10 @@ static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
public EditLine *
el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
{
-
- EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
+ EditLine *el = el_malloc(sizeof(*el));
if (el == NULL)
- return (NULL);
+ return NULL;
memset(el, 0, sizeof(EditLine));
@@ -69,8 +71,11 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
el->el_errfile = ferr;
el->el_infd = fileno(fin);
+ el->el_outfd = fileno(fout);
+ el->el_errfd = fileno(ferr);
- if ((el->el_prog = el_strdup(prog)) == NULL) {
+ el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch));
+ if (el->el_prog == NULL) {
el_free(el);
return NULL;
}
@@ -79,13 +84,18 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
* Initialize all the modules. Order is important!!!
*/
el->el_flags = 0;
+#ifdef WIDECHAR
+ setlocale(LC_CTYPE, NULL);
+ if (MB_CUR_MAX > 1)
+ el->el_flags |= CHARSET_IS_MULTIBYTE;
+#endif
- if (term_init(el) == -1) {
+ if (terminal_init(el) == -1) {
el_free(el->el_prog);
el_free(el);
return NULL;
}
- (void) key_init(el);
+ (void) keymacro_init(el);
(void) map_init(el);
if (tty_init(el) == -1)
el->el_flags |= NO_TTY;
@@ -96,7 +106,7 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
(void) sig_init(el);
(void) read_init(el);
- return (el);
+ return el;
}
@@ -112,8 +122,8 @@ el_end(EditLine *el)
el_reset(el);
- term_end(el);
- key_end(el);
+ terminal_end(el);
+ keymacro_end(el);
map_end(el);
tty_end(el);
ch_end(el);
@@ -122,8 +132,14 @@ el_end(EditLine *el)
prompt_end(el);
sig_end(el);
- el_free((ptr_t) el->el_prog);
- el_free((ptr_t) el);
+ el_free(el->el_prog);
+#ifdef WIDECHAR
+ el_free(el->el_scratch.cbuff);
+ el_free(el->el_scratch.wbuff);
+ el_free(el->el_lgcyconv.cbuff);
+ el_free(el->el_lgcyconv.wbuff);
+#endif
+ el_free(el);
}
@@ -143,27 +159,46 @@ el_reset(EditLine *el)
* set the editline parameters
*/
public int
-el_set(EditLine *el, int op, ...)
+FUN(el,set)(EditLine *el, int op, ...)
{
va_list ap;
int rv = 0;
if (el == NULL)
- return (-1);
+ return -1;
va_start(ap, op);
switch (op) {
case EL_PROMPT:
- case EL_RPROMPT:
- rv = prompt_set(el, va_arg(ap, el_pfunc_t), op);
+ case EL_RPROMPT: {
+ el_pfunc_t p = va_arg(ap, el_pfunc_t);
+
+ rv = prompt_set(el, p, 0, op, 1);
+ break;
+ }
+
+ case EL_RESIZE: {
+ el_zfunc_t p = va_arg(ap, el_zfunc_t);
+ void *arg = va_arg(ap, void *);
+ rv = ch_resizefun(el, p, arg);
+ break;
+ }
+
+ case EL_PROMPT_ESC:
+ case EL_RPROMPT_ESC: {
+ el_pfunc_t p = va_arg(ap, el_pfunc_t);
+ int c = va_arg(ap, int);
+
+ rv = prompt_set(el, p, c, op, 1);
break;
+ }
case EL_TERMINAL:
- rv = term_set(el, va_arg(ap, char *));
+ rv = terminal_set(el, va_arg(ap, char *));
break;
case EL_EDITOR:
- rv = map_set_editor(el, va_arg(ap, char *));
+ rv = map_set_editor(el, va_arg(ap, Char *));
break;
case EL_SIGNAL:
@@ -176,40 +211,39 @@ el_set(EditLine *el, int op, ...)
case EL_BIND:
case EL_TELLTC:
case EL_SETTC:
- case EL_GETTC:
case EL_ECHOTC:
case EL_SETTY:
{
- const char *argv[20];
+ const Char *argv[20];
int i;
for (i = 1; i < 20; i++)
- if ((argv[i] = va_arg(ap, char *)) == NULL)
+ if ((argv[i] = va_arg(ap, Char *)) == NULL)
break;
switch (op) {
case EL_BIND:
- argv[0] = "bind";
+ argv[0] = STR("bind");
rv = map_bind(el, i, argv);
break;
case EL_TELLTC:
- argv[0] = "telltc";
- rv = term_telltc(el, i, argv);
+ argv[0] = STR("telltc");
+ rv = terminal_telltc(el, i, argv);
break;
case EL_SETTC:
- argv[0] = "settc";
- rv = term_settc(el, i, argv);
+ argv[0] = STR("settc");
+ rv = terminal_settc(el, i, argv);
break;
case EL_ECHOTC:
- argv[0] = "echotc";
- rv = term_echotc(el, i, argv);
+ argv[0] = STR("echotc");
+ rv = terminal_echotc(el, i, argv);
break;
case EL_SETTY:
- argv[0] = "setty";
+ argv[0] = STR("setty");
rv = tty_stty(el, i, argv);
break;
@@ -223,8 +257,8 @@ el_set(EditLine *el, int op, ...)
case EL_ADDFN:
{
- char *name = va_arg(ap, char *);
- char *help = va_arg(ap, char *);
+ Char *name = va_arg(ap, Char *);
+ Char *help = va_arg(ap, Char *);
el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func);
@@ -234,9 +268,11 @@ el_set(EditLine *el, int op, ...)
case EL_HIST:
{
hist_fun_t func = va_arg(ap, hist_fun_t);
- ptr_t ptr = va_arg(ap, char *);
+ void *ptr = va_arg(ap, void *);
rv = hist_set(el, func, ptr);
+ if (!(el->el_flags & CHARSET_IS_MULTIBYTE))
+ el->el_flags &= ~NARROW_HISTORY;
break;
}
@@ -252,6 +288,7 @@ el_set(EditLine *el, int op, ...)
{
el_rfunc_t rc = va_arg(ap, el_rfunc_t);
rv = el_read_setfn(el, rc);
+ el->el_flags &= ~NARROW_READ;
break;
}
@@ -296,9 +333,11 @@ el_set(EditLine *el, int op, ...)
break;
case 1:
el->el_outfile = fp;
+ el->el_outfd = fileno(fp);
break;
case 2:
el->el_errfile = fp;
+ el->el_errfd = fileno(fp);
break;
default:
rv = -1;
@@ -310,7 +349,7 @@ el_set(EditLine *el, int op, ...)
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
- term__flush(el);
+ terminal__flush(el);
break;
default:
@@ -319,7 +358,7 @@ el_set(EditLine *el, int op, ...)
}
va_end(ap);
- return (rv);
+ return rv;
}
@@ -327,7 +366,7 @@ el_set(EditLine *el, int op, ...)
* retrieve the editline parameters
*/
public int
-el_get(EditLine *el, int op, ...)
+FUN(el,get)(EditLine *el, int op, ...)
{
va_list ap;
int rv;
@@ -339,12 +378,22 @@ el_get(EditLine *el, int op, ...)
switch (op) {
case EL_PROMPT:
- case EL_RPROMPT:
- rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op);
+ case EL_RPROMPT: {
+ el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
+ rv = prompt_get(el, p, 0, op);
break;
+ }
+ case EL_PROMPT_ESC:
+ case EL_RPROMPT_ESC: {
+ el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
+ Char *c = va_arg(ap, Char *);
+
+ rv = prompt_get(el, p, c, op);
+ break;
+ }
case EL_EDITOR:
- rv = map_get_editor(el, va_arg(ap, const char **));
+ rv = map_get_editor(el, va_arg(ap, const Char **));
break;
case EL_SIGNAL:
@@ -358,7 +407,7 @@ el_get(EditLine *el, int op, ...)
break;
case EL_TERMINAL:
- term_get(el, va_arg(ap, const char **));
+ terminal_get(el, va_arg(ap, const char **));
rv = 0;
break;
@@ -375,7 +424,7 @@ el_get(EditLine *el, int op, ...)
switch (op) {
case EL_GETTC:
argv[0] = name;
- rv = term_gettc(el, i, argv);
+ rv = terminal_gettc(el, i, argv);
break;
default:
@@ -386,26 +435,6 @@ el_get(EditLine *el, int op, ...)
break;
}
-#if 0 /* XXX */
- case EL_ADDFN:
- {
- char *name = va_arg(ap, char *);
- char *help = va_arg(ap, char *);
- el_func_t func = va_arg(ap, el_func_t);
-
- rv = map_addfunc(el, name, help, func);
- break;
- }
-
- case EL_HIST:
- {
- hist_fun_t func = va_arg(ap, hist_fun_t);
- ptr_t ptr = va_arg(ap, char *);
- rv = hist_set(el, func, ptr);
- }
- break;
-#endif /* XXX */
-
case EL_GETCFN:
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
rv = 0;
@@ -451,18 +480,18 @@ el_get(EditLine *el, int op, ...)
}
va_end(ap);
- return (rv);
+ return rv;
}
/* el_line():
* Return editing info
*/
-public const LineInfo *
-el_line(EditLine *el)
+public const TYPE(LineInfo) *
+FUN(el,line)(EditLine *el)
{
- return (const LineInfo *) (void *) &el->el_line;
+ return (const TYPE(LineInfo) *)(void *)&el->el_line;
}
@@ -475,6 +504,9 @@ el_source(EditLine *el, const char *fname)
FILE *fp;
size_t len;
char *ptr;
+ char *path = NULL;
+ const Char *dptr;
+ int error = 0;
fp = NULL;
if (fname == NULL) {
@@ -486,25 +518,21 @@ el_source(EditLine *el, const char *fname)
#if (defined(HAVE_ISSETUGID) || defined(HAVE_IDENTITY_FUNCS))
static const char elpath[] = "/.editrc";
+ size_t plen = sizeof(elpath);
/* XXXMYSQL: Portability fix (for which platforms?) */
-#ifdef MAXPATHLEN
- char path[MAXPATHLEN];
-#else
- char path[4096];
-#endif
#ifdef HAVE_ISSETUGID
if (issetugid())
- return (-1);
+ return -1;
#elif defined(HAVE_IDENTITY_FUNCS)
if (getuid() != geteuid() || getgid() != getegid())
return (-1);
#endif
if ((ptr = getenv("HOME")) == NULL)
- return (-1);
- if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
- return (-1);
- if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
- return (-1);
+ return -1;
+ plen += strlen(ptr);
+ if ((path = el_malloc(plen * sizeof(*path))) == NULL)
+ return -1;
+ (void)snprintf(path, plen, "%s%s", ptr, elpath);
fname = path;
#else
/*
@@ -513,26 +541,37 @@ el_source(EditLine *el, const char *fname)
* to keep from inadvertently opening up the user to a
* security hole.
*/
- return (-1);
+ return -1;
#endif
}
if (fp == NULL)
fp = fopen(fname, "r");
- if (fp == NULL)
- return (-1);
+ if (fp == NULL) {
+ el_free(path);
+ return -1;
+ }
while ((ptr = fgetln(fp, &len)) != NULL) {
- if (len > 0 && ptr[len - 1] == '\n')
+ if (*ptr == '\n')
+ continue; /* Empty line. */
+ dptr = ct_decode_string(ptr, &el->el_scratch);
+ if (!dptr)
+ continue;
+ if (len > 0 && dptr[len - 1] == '\n')
--len;
- ptr[len] = '\0';
- if (parse_line(el, ptr) == -1) {
- (void) fclose(fp);
- return (-1);
- }
+
+ /* loop until first non-space char or EOL */
+ while (*dptr != '\0' && Isspace(*dptr))
+ dptr++;
+ if (*dptr == '#')
+ continue; /* ignore, this is a comment line */
+ if ((error = parse_line(el, dptr)) == -1)
+ break;
}
+ el_free(path);
(void) fclose(fp);
- return (0);
+ return error;
}
@@ -550,8 +589,8 @@ el_resize(EditLine *el)
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
/* get the correct window size */
- if (term_get_size(el, &lins, &cols))
- term_change_size(el, lins, cols);
+ if (terminal_get_size(el, &lins, &cols))
+ terminal_change_size(el, lins, cols);
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
}
@@ -564,7 +603,7 @@ public void
el_beep(EditLine *el)
{
- term_beep(el);
+ terminal_beep(el);
}
@@ -573,24 +612,25 @@ el_beep(EditLine *el)
*/
protected int
/*ARGSUSED*/
-el_editmode(EditLine *el, int argc, const char **argv)
+el_editmode(EditLine *el, int argc, const Char **argv)
{
- const char *how;
+ const Char *how;
if (argv == NULL || argc != 2 || argv[1] == NULL)
- return (-1);
+ return -1;
how = argv[1];
- if (strcmp(how, "on") == 0) {
+ if (Strcmp(how, STR("on")) == 0) {
el->el_flags &= ~EDIT_DISABLED;
tty_rawmode(el);
- } else if (strcmp(how, "off") == 0) {
+ } else if (Strcmp(how, STR("off")) == 0) {
tty_cookedmode(el);
el->el_flags |= EDIT_DISABLED;
}
else {
- (void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
- return (-1);
+ (void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n",
+ how);
+ return -1;
}
- return (0);
+ return 0;
}
diff --git a/cmd-line-utils/libedit/el.h b/cmd-line-utils/libedit/el.h
index 05d88ad88ba..403a44aa806 100644
--- a/cmd-line-utils/libedit/el.h
+++ b/cmd-line-utils/libedit/el.h
@@ -1,4 +1,4 @@
-/* $NetBSD: el.h,v 1.17 2006/12/15 22:13:33 christos Exp $ */
+/* $NetBSD: el.h,v 1.25 2011/07/29 23:44:44 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -46,15 +46,21 @@
#define VIDEFAULT
#define ANCHOR
+#include "histedit.h"
+#include "chartype.h"
#include <stdio.h>
#include <sys/types.h>
-#define EL_BUFSIZ 1024 /* Maximum line size */
+#define EL_BUFSIZ ((size_t)4096) /* Maximum line size */
-#define HANDLE_SIGNALS 0x01
-#define NO_TTY 0x02
-#define EDIT_DISABLED 0x04
-#define UNBUFFERED 0x08
+#define HANDLE_SIGNALS 0x01
+#define NO_TTY 0x02
+#define EDIT_DISABLED 0x04
+#define UNBUFFERED 0x08
+#define CHARSET_IS_MULTIBYTE 0x10
+#define IGNORE_EXTCHARS 0x20 /* Ignore characters read > 0xff */
+#define NARROW_HISTORY 0x40
+#define NARROW_READ 0x80
typedef int bool_t; /* True or not */
@@ -66,10 +72,10 @@ typedef struct coord_t { /* Position on the screen */
} coord_t;
typedef struct el_line_t {
- char *buffer; /* Input line */
- char *cursor; /* Cursor position */
- char *lastchar; /* Last character */
- const char *limit; /* Max position */
+ Char *buffer; /* Input line */
+ Char *cursor; /* Cursor position */
+ Char *lastchar; /* Last character */
+ const Char *limit; /* Max position */
} el_line_t;
/*
@@ -82,21 +88,20 @@ typedef struct el_state_t {
int metanext; /* Is the next char a meta char */
el_action_t lastcmd; /* Previous command */
el_action_t thiscmd; /* this command */
- char thisch; /* char that generated it */
+ Char thisch; /* char that generated it */
} el_state_t;
/*
* Until we come up with something better...
*/
-#define el_strdup(a) strdup(a)
#define el_malloc(a) malloc(a)
#define el_realloc(a,b) realloc(a, b)
#define el_free(a) free(a)
#include "tty.h"
#include "prompt.h"
-#include "key.h"
-#include "el_term.h"
+#include "keymacro.h"
+#include "el_terminal.h"
#include "refresh.h"
#include "chared.h"
#include "common.h"
@@ -109,33 +114,41 @@ typedef struct el_state_t {
#include "read.h"
struct editline {
- char *el_prog; /* the program name */
+ Char *el_prog; /* the program name */
FILE *el_infile; /* Stdio stuff */
FILE *el_outfile; /* Stdio stuff */
FILE *el_errfile; /* Stdio stuff */
int el_infd; /* Input file descriptor */
+ int el_outfd; /* Output file descriptor */
+ int el_errfd; /* Error file descriptor */
int el_flags; /* Various flags. */
+ int el_errno; /* Local copy of errno */
coord_t el_cursor; /* Cursor location */
- char **el_display; /* Real screen image = what is there */
- char **el_vdisplay; /* Virtual screen image = what we see */
+ Char **el_display; /* Real screen image = what is there */
+ Char **el_vdisplay; /* Virtual screen image = what we see */
void *el_data; /* Client data */
el_line_t el_line; /* The current line information */
el_state_t el_state; /* Current editor state */
- el_term_t el_term; /* Terminal dependent stuff */
+ el_terminal_t el_terminal; /* Terminal dependent stuff */
el_tty_t el_tty; /* Tty dependent stuff */
el_refresh_t el_refresh; /* Refresh stuff */
el_prompt_t el_prompt; /* Prompt stuff */
el_prompt_t el_rprompt; /* Prompt stuff */
el_chared_t el_chared; /* Characted editor stuff */
el_map_t el_map; /* Key mapping stuff */
- el_key_t el_key; /* Key binding stuff */
+ el_keymacro_t el_keymacro; /* Key binding stuff */
el_history_t el_history; /* History stuff */
el_search_t el_search; /* Search stuff */
el_signal_t el_signal; /* Signal handling stuff */
el_read_t el_read; /* Character reading stuff */
+#ifdef WIDECHAR
+ ct_buffer_t el_scratch; /* Scratch conversion buffer */
+ ct_buffer_t el_lgcyconv; /* Buffer for legacy wrappers */
+ LineInfo el_lgcylinfo; /* Legacy LineInfo buffer */
+#endif
};
-protected int el_editmode(EditLine *, int, const char **);
+protected int el_editmode(EditLine *, int, const Char **);
/* XXXMYSQL: Bug#23097 mysql can't insert korean on mysql prompt. */
#define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1)
diff --git a/cmd-line-utils/libedit/el_term.h b/cmd-line-utils/libedit/el_terminal.h
index 0e7ddd555f4..807c651783e 100644
--- a/cmd-line-utils/libedit/el_term.h
+++ b/cmd-line-utils/libedit/el_terminal.h
@@ -1,4 +1,4 @@
-/* $NetBSD: term.h,v 1.19 2008/09/10 15:45:37 christos Exp $ */
+/* $NetBSD: terminal.h,v 1.3 2011/07/29 23:44:45 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,17 +37,17 @@
/*
* el.term.h: Termcap header
*/
-#ifndef _h_el_term
-#define _h_el_term
+#ifndef _h_el_terminal
+#define _h_el_terminal
#include "histedit.h"
typedef struct { /* Symbolic function key bindings */
- const char *name; /* name of the key */
+ const Char *name; /* name of the key */
int key; /* Index in termcap table */
- key_value_t fun; /* Function bound to it */
+ keymacro_value_t fun; /* Function bound to it */
int type; /* Type of function */
-} fkey_t;
+} funckey_t;
typedef struct {
const char *t_name; /* the terminal name */
@@ -63,12 +63,12 @@ typedef struct {
#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */
#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */
char *t_buf; /* Termcap buffer */
- int t_loc; /* location used */
+ size_t t_loc; /* location used */
char **t_str; /* termcap strings */
int *t_val; /* termcap values */
char *t_cap; /* Termcap buffer */
- fkey_t *t_fkey; /* Array of keys */
-} el_term_t;
+ funckey_t *t_fkey; /* Array of keys */
+} el_terminal_t;
/*
* fKey indexes
@@ -81,36 +81,36 @@ typedef struct {
#define A_K_EN 5
#define A_K_NKEYS 6
-protected void term_move_to_line(EditLine *, int);
-protected void term_move_to_char(EditLine *, int);
-protected void term_clear_EOL(EditLine *, int);
-protected void term_overwrite(EditLine *, const char *, int);
-protected void term_insertwrite(EditLine *, char *, int);
-protected void term_deletechars(EditLine *, int);
-protected void term_clear_screen(EditLine *);
-protected void term_beep(EditLine *);
-protected int term_change_size(EditLine *, int, int);
-protected int term_get_size(EditLine *, int *, int *);
-protected int term_init(EditLine *);
-protected void term_bind_arrow(EditLine *);
-protected void term_print_arrow(EditLine *, const char *);
-protected int term_clear_arrow(EditLine *, const char *);
-protected int term_set_arrow(EditLine *, const char *, key_value_t *, int);
-protected void term_end(EditLine *);
-protected void term_get(EditLine *, const char **);
-protected int term_set(EditLine *, const char *);
-protected int term_settc(EditLine *, int, const char **);
-protected int term_gettc(EditLine *, int, char **);
-protected int term_telltc(EditLine *, int, const char **);
-protected int term_echotc(EditLine *, int, const char **);
-protected void term_writec(EditLine *, int);
-protected int term__putc(EditLine *, int);
-protected void term__flush(EditLine *);
+protected void terminal_move_to_line(EditLine *, int);
+protected void terminal_move_to_char(EditLine *, int);
+protected void terminal_clear_EOL(EditLine *, int);
+protected void terminal_overwrite(EditLine *, const Char *, size_t);
+protected void terminal_insertwrite(EditLine *, Char *, int);
+protected void terminal_deletechars(EditLine *, int);
+protected void terminal_clear_screen(EditLine *);
+protected void terminal_beep(EditLine *);
+protected int terminal_change_size(EditLine *, int, int);
+protected int terminal_get_size(EditLine *, int *, int *);
+protected int terminal_init(EditLine *);
+protected void terminal_bind_arrow(EditLine *);
+protected void terminal_print_arrow(EditLine *, const Char *);
+protected int terminal_clear_arrow(EditLine *, const Char *);
+protected int terminal_set_arrow(EditLine *, const Char *, keymacro_value_t *, int);
+protected void terminal_end(EditLine *);
+protected void terminal_get(EditLine *, const char **);
+protected int terminal_set(EditLine *, const char *);
+protected int terminal_settc(EditLine *, int, const Char **);
+protected int terminal_gettc(EditLine *, int, char **);
+protected int terminal_telltc(EditLine *, int, const Char **);
+protected int terminal_echotc(EditLine *, int, const Char **);
+protected void terminal_writec(EditLine *, Int);
+protected int terminal__putc(EditLine *, Int);
+protected void terminal__flush(EditLine *);
/*
* Easy access macros
*/
-#define EL_FLAGS (el)->el_term.t_flags
+#define EL_FLAGS (el)->el_terminal.t_flags
#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT)
#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE)
@@ -122,4 +122,4 @@ protected void term__flush(EditLine *);
#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS)
#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS)
-#endif /* _h_el_term */
+#endif /* _h_el_terminal */
diff --git a/cmd-line-utils/libedit/eln.c b/cmd-line-utils/libedit/eln.c
new file mode 100644
index 00000000000..4b9f16c38f3
--- /dev/null
+++ b/cmd-line-utils/libedit/eln.c
@@ -0,0 +1,364 @@
+/* $NetBSD: eln.c,v 1.13 2011/08/16 16:25:15 christos Exp $ */
+
+/*-
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * 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 reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 THE NETBSD FOUNDATION, INC. 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 THE FOUNDATION 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 "config.h"
+#if !defined(lint) && !defined(SCCSID)
+#endif /* not lint && not SCCSID */
+
+#include "histedit.h"
+#include "el.h"
+#include "read.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+public int
+el_getc(EditLine *el, char *cp)
+{
+ int num_read;
+ wchar_t wc = 0;
+
+ num_read = el_wgetc (el, &wc);
+
+ if (num_read > 0)
+ *cp = (char)wc;
+ return num_read;
+}
+
+
+public void
+el_push(EditLine *el, const char *str)
+{
+ /* Using multibyte->wide string decoding works fine under single-byte
+ * character sets too, and Does The Right Thing. */
+ el_wpush(el, ct_decode_string(str, &el->el_lgcyconv));
+}
+
+
+public const char *
+el_gets(EditLine *el, int *nread)
+{
+ const wchar_t *tmp;
+
+ tmp = el_wgets(el, nread);
+ return ct_encode_string(tmp, &el->el_lgcyconv);
+}
+
+
+public int
+el_parse(EditLine *el, int argc, const char *argv[])
+{
+ int ret;
+ const wchar_t **wargv;
+
+ wargv = (const wchar_t **)
+ ct_decode_argv(argc, argv, &el->el_lgcyconv);
+ if (!wargv)
+ return -1;
+ ret = el_wparse(el, argc, wargv);
+ ct_free_argv(wargv);
+
+ return ret;
+}
+
+
+public int
+el_set(EditLine *el, int op, ...)
+{
+ va_list ap;
+ int ret;
+
+ if (!el)
+ return -1;
+ va_start(ap, op);
+
+ switch (op) {
+ case EL_PROMPT: /* el_pfunc_t */
+ case EL_RPROMPT: {
+ el_pfunc_t p = va_arg(ap, el_pfunc_t);
+ ret = prompt_set(el, p, 0, op, 0);
+ break;
+ }
+
+ case EL_RESIZE: {
+ el_zfunc_t p = va_arg(ap, el_zfunc_t);
+ void *arg = va_arg(ap, void *);
+ ret = ch_resizefun(el, p, arg);
+ break;
+ }
+
+ case EL_TERMINAL: /* const char * */
+ ret = el_wset(el, op, va_arg(ap, char *));
+ break;
+
+ case EL_EDITOR: /* const wchar_t * */
+ ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *),
+ &el->el_lgcyconv));
+ break;
+
+ case EL_SIGNAL: /* int */
+ case EL_EDITMODE:
+ case EL_UNBUFFERED:
+ case EL_PREP_TERM:
+ ret = el_wset(el, op, va_arg(ap, int));
+ break;
+
+ case EL_BIND: /* const char * list -> const wchar_t * list */
+ case EL_TELLTC:
+ case EL_SETTC:
+ case EL_ECHOTC:
+ case EL_SETTY: {
+ const char *argv[20];
+ int i;
+ const wchar_t **wargv;
+ for (i = 1; i < (int)__arraycount(argv); ++i)
+ if ((argv[i] = va_arg(ap, char *)) == NULL)
+ break;
+ argv[0] = NULL;
+ wargv = (const wchar_t **)
+ ct_decode_argv(i, argv, &el->el_lgcyconv);
+ if (!wargv) {
+ ret = -1;
+ goto out;
+ }
+ /*
+ * AFAIK we can't portably pass through our new wargv to
+ * el_wset(), so we have to reimplement the body of
+ * el_wset() for these ops.
+ */
+ switch (op) {
+ case EL_BIND:
+ wargv[0] = STR("bind");
+ ret = map_bind(el, i, wargv);
+ break;
+ case EL_TELLTC:
+ wargv[0] = STR("telltc");
+ ret = terminal_telltc(el, i, wargv);
+ break;
+ case EL_SETTC:
+ wargv[0] = STR("settc");
+ ret = terminal_settc(el, i, wargv);
+ break;
+ case EL_ECHOTC:
+ wargv[0] = STR("echotc");
+ ret = terminal_echotc(el, i, wargv);
+ break;
+ case EL_SETTY:
+ wargv[0] = STR("setty");
+ ret = tty_stty(el, i, wargv);
+ break;
+ default:
+ ret = -1;
+ }
+ ct_free_argv(wargv);
+ break;
+ }
+
+ /* XXX: do we need to change el_func_t too? */
+ case EL_ADDFN: { /* const char *, const char *, el_func_t */
+ const char *args[2];
+ el_func_t func;
+ wchar_t **wargv;
+
+ args[0] = va_arg(ap, const char *);
+ args[1] = va_arg(ap, const char *);
+ func = va_arg(ap, el_func_t);
+
+ wargv = ct_decode_argv(2, args, &el->el_lgcyconv);
+ if (!wargv) {
+ ret = -1;
+ goto out;
+ }
+ // XXX: The two strdup's leak
+ ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
+ func);
+ ct_free_argv(wargv);
+ break;
+ }
+ case EL_HIST: { /* hist_fun_t, const char * */
+ hist_fun_t fun = va_arg(ap, hist_fun_t);
+ void *ptr = va_arg(ap, void *);
+ ret = hist_set(el, fun, ptr);
+ el->el_flags |= NARROW_HISTORY;
+ break;
+ }
+ /* XXX: do we need to change el_rfunc_t? */
+ case EL_GETCFN: /* el_rfunc_t */
+ ret = el_wset(el, op, va_arg(ap, el_rfunc_t));
+ el->el_flags |= NARROW_READ;
+ break;
+ case EL_CLIENTDATA: /* void * */
+ ret = el_wset(el, op, va_arg(ap, void *));
+ break;
+ case EL_SETFP: { /* int, FILE * */
+ int what = va_arg(ap, int);
+ FILE *fp = va_arg(ap, FILE *);
+ ret = el_wset(el, op, what, fp);
+ break;
+ }
+ case EL_PROMPT_ESC: /* el_pfunc_t, char */
+ case EL_RPROMPT_ESC: {
+ el_pfunc_t p = va_arg(ap, el_pfunc_t);
+ char c = (char)va_arg(ap, int);
+ ret = prompt_set(el, p, c, op, 0);
+ break;
+ }
+ default:
+ ret = -1;
+ break;
+ }
+
+out:
+ va_end(ap);
+ return ret;
+}
+
+
+public int
+el_get(EditLine *el, int op, ...)
+{
+ va_list ap;
+ int ret;
+
+ if (!el)
+ return -1;
+
+ va_start(ap, op);
+
+ switch (op) {
+ case EL_PROMPT: /* el_pfunc_t * */
+ case EL_RPROMPT: {
+ el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
+ ret = prompt_get(el, p, 0, op);
+ break;
+ }
+
+ case EL_PROMPT_ESC: /* el_pfunc_t *, char **/
+ case EL_RPROMPT_ESC: {
+ el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
+ char *c = va_arg(ap, char *);
+ wchar_t wc = 0;
+ ret = prompt_get(el, p, &wc, op);
+ *c = (char)wc;
+ break;
+ }
+
+ case EL_EDITOR: {
+ const char **p = va_arg(ap, const char **);
+ const wchar_t *pw;
+ ret = el_wget(el, op, &pw);
+ *p = ct_encode_string(pw, &el->el_lgcyconv);
+ if (!el->el_lgcyconv.csize)
+ ret = -1;
+ break;
+ }
+
+ case EL_TERMINAL: /* const char ** */
+ ret = el_wget(el, op, va_arg(ap, const char **));
+ break;
+
+ case EL_SIGNAL: /* int * */
+ case EL_EDITMODE:
+ case EL_UNBUFFERED:
+ case EL_PREP_TERM:
+ ret = el_wget(el, op, va_arg(ap, int *));
+ break;
+
+ case EL_GETTC: {
+ char *argv[20];
+ static char gettc[] = "gettc";
+ int i;
+ for (i = 1; i < (int)__arraycount(argv); ++i)
+ if ((argv[i] = va_arg(ap, char *)) == NULL)
+ break;
+ argv[0] = gettc;
+ ret = terminal_gettc(el, i, argv);
+ break;
+ }
+
+ /* XXX: do we need to change el_rfunc_t? */
+ case EL_GETCFN: /* el_rfunc_t */
+ ret = el_wget(el, op, va_arg(ap, el_rfunc_t *));
+ break;
+
+ case EL_CLIENTDATA: /* void ** */
+ ret = el_wget(el, op, va_arg(ap, void **));
+ break;
+
+ case EL_GETFP: { /* int, FILE ** */
+ int what = va_arg(ap, int);
+ FILE **fpp = va_arg(ap, FILE **);
+ ret = el_wget(el, op, what, fpp);
+ break;
+ }
+
+ default:
+ ret = -1;
+ break;
+ }
+
+ va_end(ap);
+ return ret;
+}
+
+
+const LineInfo *
+el_line(EditLine *el)
+{
+ const LineInfoW *winfo = el_wline(el);
+ LineInfo *info = &el->el_lgcylinfo;
+ size_t offset;
+ const Char *p;
+
+ info->buffer = ct_encode_string(winfo->buffer, &el->el_lgcyconv);
+
+ offset = 0;
+ for (p = winfo->buffer; p < winfo->cursor; p++)
+ offset += ct_enc_width(*p);
+ info->cursor = info->buffer + offset;
+
+ offset = 0;
+ for (p = winfo->buffer; p < winfo->lastchar; p++)
+ offset += ct_enc_width(*p);
+ info->lastchar = info->buffer + offset;
+
+ return info;
+}
+
+
+int
+el_insertstr(EditLine *el, const char *str)
+{
+ return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
+}
diff --git a/cmd-line-utils/libedit/emacs.c b/cmd-line-utils/libedit/emacs.c
index 135bd75f566..554d3970485 100644
--- a/cmd-line-utils/libedit/emacs.c
+++ b/cmd-line-utils/libedit/emacs.c
@@ -1,4 +1,4 @@
-/* $NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $ */
+/* $NetBSD: emacs.c,v 1.25 2011/07/29 15:16:33 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -51,22 +51,22 @@ static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
*/
protected el_action_t
/*ARGSUSED*/
-em_delete_or_list(EditLine *el, int c)
+em_delete_or_list(EditLine *el, Int c)
{
if (el->el_line.cursor == el->el_line.lastchar) {
/* if I'm at the end */
if (el->el_line.cursor == el->el_line.buffer) {
/* and the beginning */
- term_writec(el, c); /* then do an EOF */
- return (CC_EOF);
+ terminal_writec(el, c); /* then do an EOF */
+ return CC_EOF;
} else {
/*
* Here we could list completions, but it is an
* error right now
*/
- term_beep(el);
- return (CC_ERROR);
+ terminal_beep(el);
+ return CC_ERROR;
}
} else {
if (el->el_state.doingarg)
@@ -76,7 +76,7 @@ em_delete_or_list(EditLine *el, int c)
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
/* bounds check */
- return (CC_REFRESH);
+ return CC_REFRESH;
}
}
@@ -87,12 +87,12 @@ em_delete_or_list(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
+em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
{
- char *cp, *p, *kp;
+ Char *cp, *p, *kp;
if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
+ return CC_ERROR;
cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword);
@@ -102,11 +102,11 @@ em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
*kp++ = *p;
el->el_chared.c_kill.last = kp;
- c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
+ c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
/* bounds check */
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -116,23 +116,24 @@ em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_yank(EditLine *el, int c __attribute__((__unused__)))
+em_yank(EditLine *el, Int c __attribute__((__unused__)))
{
- char *kp, *cp;
+ Char *kp, *cp;
if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
- return (CC_NORM);
+ return CC_NORM;
if (el->el_line.lastchar +
(el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
el->el_line.limit)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_chared.c_kill.mark = el->el_line.cursor;
cp = el->el_line.cursor;
/* open the space, */
- c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
+ c_insert(el,
+ (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf));
/* copy the chars */
for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
*cp++ = *kp;
@@ -141,7 +142,7 @@ em_yank(EditLine *el, int c __attribute__((__unused__)))
if (el->el_state.argument == 1)
el->el_line.cursor = cp;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -151,9 +152,9 @@ em_yank(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_kill_line(EditLine *el, int c __attribute__((__unused__)))
+em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
{
- char *kp, *cp;
+ Char *kp, *cp;
cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf;
@@ -163,7 +164,7 @@ em_kill_line(EditLine *el, int c __attribute__((__unused__)))
/* zap! -- delete all of it */
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -173,12 +174,12 @@ em_kill_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_kill_region(EditLine *el, int c __attribute__((__unused__)))
+em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
{
- char *kp, *cp;
+ Char *kp, *cp;
if (!el->el_chared.c_kill.mark)
- return (CC_ERROR);
+ return CC_ERROR;
if (el->el_chared.c_kill.mark > el->el_line.cursor) {
cp = el->el_line.cursor;
@@ -186,17 +187,17 @@ em_kill_region(EditLine *el, int c __attribute__((__unused__)))
while (cp < el->el_chared.c_kill.mark)
*kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp;
- c_delafter(el, cp - el->el_line.cursor);
+ c_delafter(el, (int)(cp - el->el_line.cursor));
} else { /* mark is before cursor */
cp = el->el_chared.c_kill.mark;
kp = el->el_chared.c_kill.buf;
while (cp < el->el_line.cursor)
*kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp;
- c_delbefore(el, cp - el->el_chared.c_kill.mark);
+ c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
el->el_line.cursor = el->el_chared.c_kill.mark;
}
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -206,12 +207,12 @@ em_kill_region(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_copy_region(EditLine *el, int c __attribute__((__unused__)))
+em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
{
- char *kp, *cp;
+ Char *kp, *cp;
if (!el->el_chared.c_kill.mark)
- return (CC_ERROR);
+ return CC_ERROR;
if (el->el_chared.c_kill.mark > el->el_line.cursor) {
cp = el->el_line.cursor;
@@ -226,7 +227,7 @@ em_copy_region(EditLine *el, int c __attribute__((__unused__)))
*kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp;
}
- return (CC_NORM);
+ return CC_NORM;
}
@@ -235,7 +236,7 @@ em_copy_region(EditLine *el, int c __attribute__((__unused__)))
* Gosling emacs transpose chars [^T]
*/
protected el_action_t
-em_gosmacs_transpose(EditLine *el, int c)
+em_gosmacs_transpose(EditLine *el, Int c)
{
if (el->el_line.cursor > &el->el_line.buffer[1]) {
@@ -243,9 +244,9 @@ em_gosmacs_transpose(EditLine *el, int c)
c = el->el_line.cursor[-2];
el->el_line.cursor[-2] = el->el_line.cursor[-1];
el->el_line.cursor[-1] = c;
- return (CC_REFRESH);
+ return CC_REFRESH;
} else
- return (CC_ERROR);
+ return CC_ERROR;
}
@@ -255,10 +256,10 @@ em_gosmacs_transpose(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-em_next_word(EditLine *el, int c __attribute__((__unused__)))
+em_next_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_line.cursor = c__next_word(el->el_line.cursor,
el->el_line.lastchar,
@@ -268,9 +269,9 @@ em_next_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -280,21 +281,21 @@ em_next_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_upper_case(EditLine *el, int c __attribute__((__unused__)))
+em_upper_case(EditLine *el, Int c __attribute__((__unused__)))
{
- char *cp, *ep;
+ Char *cp, *ep;
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++)
- if (islower((unsigned char)*cp))
- *cp = toupper((unsigned char)*cp);
+ if (Islower(*cp))
+ *cp = Toupper(*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -304,29 +305,29 @@ em_upper_case(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
+em_capitol_case(EditLine *el, Int c __attribute__((__unused__)))
{
- char *cp, *ep;
+ Char *cp, *ep;
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++) {
- if (isalpha((unsigned char)*cp)) {
- if (islower((unsigned char)*cp))
- *cp = toupper((unsigned char)*cp);
+ if (Isalpha(*cp)) {
+ if (Islower(*cp))
+ *cp = Toupper(*cp);
cp++;
break;
}
}
for (; cp < ep; cp++)
- if (isupper((unsigned char)*cp))
- *cp = tolower((unsigned char)*cp);
+ if (Isupper(*cp))
+ *cp = Tolower(*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -336,21 +337,21 @@ em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_lower_case(EditLine *el, int c __attribute__((__unused__)))
+em_lower_case(EditLine *el, Int c __attribute__((__unused__)))
{
- char *cp, *ep;
+ Char *cp, *ep;
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++)
- if (isupper((unsigned char)*cp))
- *cp = tolower((unsigned char)*cp);
+ if (Isupper(*cp))
+ *cp = Tolower(*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -360,11 +361,11 @@ em_lower_case(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_set_mark(EditLine *el, int c __attribute__((__unused__)))
+em_set_mark(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_chared.c_kill.mark = el->el_line.cursor;
- return (CC_NORM);
+ return CC_NORM;
}
@@ -374,14 +375,14 @@ em_set_mark(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
+em_exchange_mark(EditLine *el, Int c __attribute__((__unused__)))
{
- char *cp;
+ Char *cp;
cp = el->el_line.cursor;
el->el_line.cursor = el->el_chared.c_kill.mark;
el->el_chared.c_kill.mark = cp;
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -391,14 +392,14 @@ em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
+em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
{ /* multiply current argument by 4 */
if (el->el_state.argument > 1000000)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_state.doingarg = 1;
el->el_state.argument *= 4;
- return (CC_ARGHACK);
+ return CC_ARGHACK;
}
@@ -408,11 +409,11 @@ em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_meta_next(EditLine *el, int c __attribute__((__unused__)))
+em_meta_next(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_state.metanext = 1;
- return (CC_ARGHACK);
+ return CC_ARGHACK;
}
@@ -421,12 +422,12 @@ em_meta_next(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
+em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
MODE_REPLACE : MODE_INSERT;
- return (CC_NORM);
+ return CC_NORM;
}
@@ -435,25 +436,25 @@ em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
+em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
- char *cp, *oldc, *dp;
+ Char *cp, *oldc, *dp;
if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
+ return CC_ERROR;
oldc = el->el_line.cursor;
/* does a bounds check */
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
el->el_state.argument, ce__isword);
- c_insert(el, oldc - cp);
+ c_insert(el, (int)(oldc - cp));
for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
*dp++ = *cp;
el->el_line.cursor = dp;/* put cursor at end */
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -462,11 +463,11 @@ em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
+em_inc_search_next(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
- return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
+ return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
}
@@ -475,11 +476,11 @@ em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
+em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
- return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
+ return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
}
@@ -489,11 +490,11 @@ em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
+em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
- return (CC_ERROR);
+ return CC_ERROR;
if (el->el_state.doingarg)
c_delbefore(el, el->el_state.argument);
@@ -502,5 +503,5 @@ em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
el->el_line.cursor -= el->el_state.argument;
if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
diff --git a/cmd-line-utils/libedit/filecomplete.c b/cmd-line-utils/libedit/filecomplete.c
index 05bd10e9f9e..b67b54510bf 100644
--- a/cmd-line-utils/libedit/filecomplete.c
+++ b/cmd-line-utils/libedit/filecomplete.c
@@ -1,4 +1,4 @@
-/* $NetBSD: filecomplete.c,v 1.13 2009/01/26 17:32:41 apb Exp $ */
+/* $NetBSD: filecomplete.c,v 1.31 2011/09/16 16:13:16 plunky Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -78,8 +78,8 @@ extern char *alloca ();
#include "histedit.h"
#include "filecomplete.h"
-static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
- '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
+static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
+ '$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
/********************************/
@@ -95,12 +95,16 @@ static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
char *
fn_tilde_expand(const char *txt)
{
+#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
+ struct passwd pwres;
+ char pwbuf[1024];
+#endif
struct passwd *pass;
char *temp;
size_t len = 0;
if (txt[0] != '~')
- return (strdup(txt));
+ return strdup(txt);
temp = strchr(txt + 1, '/');
if (temp == NULL) {
@@ -108,33 +112,49 @@ fn_tilde_expand(const char *txt)
if (temp == NULL)
return NULL;
} else {
- len = temp - txt + 1; /* text until string after slash */
- temp = malloc(len);
+ /* text until string after slash */
+ len = (size_t)(temp - txt + 1);
+ temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
(void)strncpy(temp, txt + 1, len - 2);
temp[len - 2] = '\0';
}
- /* XXXMYSQL: use non-_r functions for now */
if (temp[0] == 0) {
+#ifdef HAVE_GETPW_R_POSIX
+ if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf),
+ &pass) != 0)
+ pass = NULL;
+#elif HAVE_GETPW_R_DRAFT
+ pass = getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf));
+#else
pass = getpwuid(getuid());
+#endif
} else {
+#ifdef HAVE_GETPW_R_POSIX
+ if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
+ pass = NULL;
+#elif HAVE_GETPW_R_DRAFT
+ pass = getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf));
+#else
pass = getpwnam(temp);
+#endif
}
- free(temp); /* value no more needed */
+ el_free(temp); /* value no more needed */
if (pass == NULL)
- return (strdup(txt));
+ return strdup(txt);
/* update pointer txt to point at string immedially following */
/* first slash */
txt += len;
- temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
+ len = strlen(pass->pw_dir) + 1 + strlen(txt) + 1;
+ temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
- (void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
+ (void)snprintf(temp, len, "%s/%s", pass->pw_dir, txt);
- return (temp);
+ return temp;
}
@@ -160,23 +180,29 @@ fn_filename_completion_function(const char *text, int state)
if (temp) {
char *nptr;
temp++;
- nptr = realloc(filename, strlen(temp) + 1);
+ nptr = el_realloc(filename, (strlen(temp) + 1) *
+ sizeof(*nptr));
if (nptr == NULL) {
- free(filename);
+ el_free(filename);
+ filename = NULL;
return NULL;
}
filename = nptr;
(void)strcpy(filename, temp);
- len = temp - text; /* including last slash */
- nptr = realloc(dirname, len + 1);
+ len = (size_t)(temp - text); /* including last slash */
+
+ nptr = el_realloc(dirname, (len + 1) *
+ sizeof(*nptr));
if (nptr == NULL) {
- free(filename);
+ el_free(dirname);
+ dirname = NULL;
return NULL;
}
dirname = nptr;
(void)strncpy(dirname, text, len);
dirname[len] = '\0';
} else {
+ el_free(filename);
if (*text == 0)
filename = NULL;
else {
@@ -184,6 +210,7 @@ fn_filename_completion_function(const char *text, int state)
if (filename == NULL)
return NULL;
}
+ el_free(dirname);
dirname = NULL;
}
@@ -193,12 +220,14 @@ fn_filename_completion_function(const char *text, int state)
}
/* support for ``~user'' syntax */
- free(dirpath);
- if (dirname == NULL && (dirname = strdup("./")) == NULL)
- return NULL;
-
- if (*dirname == '~')
+ el_free(dirpath);
+ dirpath = NULL;
+ if (dirname == NULL) {
+ if ((dirname = strdup("")) == NULL)
+ return NULL;
+ dirpath = strdup("./");
+ } else if (*dirname == '~')
dirpath = fn_tilde_expand(dirname);
else
dirpath = strdup(dirname);
@@ -208,7 +237,7 @@ fn_filename_completion_function(const char *text, int state)
dir = opendir(dirpath);
if (!dir)
- return (NULL); /* cannot open the directory */
+ return NULL; /* cannot open the directory */
/* will be used in cycle */
filename_len = filename ? strlen(filename) : 0;
@@ -243,17 +272,18 @@ fn_filename_completion_function(const char *text, int state)
len = strlen(entry->d_name);
#endif
- temp = malloc(strlen(dirname) + len + 1);
+ len = strlen(dirname) + len + 1;
+ temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
- (void)sprintf(temp, "%s%s", dirname, entry->d_name);
+ (void)snprintf(temp, len, "%s%s", dirname, entry->d_name);
} else {
(void)closedir(dir);
dir = NULL;
temp = NULL;
}
- return (temp);
+ return temp;
}
@@ -270,7 +300,7 @@ append_char_function(const char *name)
rs = "/";
out:
if (expname)
- free(expname);
+ el_free(expname);
return rs;
}
/*
@@ -293,10 +323,10 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
char **nmatch_list;
while (matches + 3 >= match_list_len)
match_list_len <<= 1;
- nmatch_list = realloc(match_list,
- match_list_len * sizeof(char *));
+ nmatch_list = el_realloc(match_list,
+ match_list_len * sizeof(*nmatch_list));
if (nmatch_list == NULL) {
- free(match_list);
+ el_free(match_list);
return NULL;
}
match_list = nmatch_list;
@@ -319,9 +349,9 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
max_equal = i;
}
- retstr = malloc(max_equal + 1);
+ retstr = el_malloc((max_equal + 1) * sizeof(*retstr));
if (retstr == NULL) {
- free(match_list);
+ el_free(match_list);
return NULL;
}
(void)strncpy(retstr, match_list[1], max_equal);
@@ -329,9 +359,9 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
match_list[0] = retstr;
/* add NULL as last pointer to the array */
- match_list[matches + 1] = (char *) NULL;
+ match_list[matches + 1] = NULL;
- return (match_list);
+ return match_list;
}
/*
@@ -348,37 +378,47 @@ _fn_qsort_string_compare(const void *i1, const void *i2)
/*
* Display list of strings in columnar format on readline's output stream.
- * 'matches' is list of strings, 'len' is number of strings in 'matches',
- * 'max' is maximum length of string in 'matches'.
+ * 'matches' is list of strings, 'num' is number of strings in 'matches',
+ * 'width' is maximum length of string in 'matches'.
+ *
+ * matches[0] is not one of the match strings, but it is counted in
+ * num, so the strings are matches[1] *through* matches[num-1].
*/
void
-fn_display_match_list (EditLine *el, char **matches, int len, int max)
+fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
{
- int i, idx, limit, count;
- int screenwidth = el->el_term.t_size.h;
+ size_t line, lines, col, cols, thisguy;
+ int screenwidth = el->el_terminal.t_size.h;
+
+ /* Ignore matches[0]. Avoid 1-based array logic below. */
+ matches++;
+ num--;
/*
- * Find out how many entries can be put on one line, count
- * with two spaces between strings.
+ * Find out how many entries can be put on one line; count
+ * with one space between strings the same way it's printed.
*/
- limit = screenwidth / (max + 2);
- if (limit == 0)
- limit = 1;
-
- /* how many lines of output */
- count = len / limit;
- if (count * limit < len)
- count++;
-
- /* Sort the items if they are not already sorted. */
- qsort(&matches[1], (size_t)(len - 1), sizeof(char *),
- _fn_qsort_string_compare);
-
- idx = 1;
- for(; count > 0; count--) {
- for(i = 0; i < limit && matches[idx]; i++, idx++)
- (void)fprintf(el->el_outfile, "%-*s ", max,
- matches[idx]);
+ cols = (size_t)screenwidth / (width + 1);
+ if (cols == 0)
+ cols = 1;
+
+ /* how many lines of output, rounded up */
+ lines = (num + cols - 1) / cols;
+
+ /* Sort the items. */
+ qsort(matches, num, sizeof(char *), _fn_qsort_string_compare);
+
+ /*
+ * On the ith line print elements i, i+lines, i+lines*2, etc.
+ */
+ for (line = 0; line < lines; line++) {
+ for (col = 0; col < cols; col++) {
+ thisguy = line + col * lines;
+ if (thisguy >= num)
+ break;
+ (void)fprintf(el->el_outfile, "%s%-*s",
+ col == 0 ? "" : " ", (int)width, matches[thisguy]);
+ }
(void)fprintf(el->el_outfile, "\n");
}
}
@@ -399,13 +439,14 @@ int
fn_complete(EditLine *el,
char *(*complet_func)(const char *, int),
char **(*attempted_completion_function)(const char *, int, int),
- const char *word_break, const char *special_prefixes,
- const char *(*app_func)(const char *), int query_items,
+ const Char *word_break, const Char *special_prefixes,
+ const char *(*app_func)(const char *), size_t query_items,
int *completion_type, int *over, int *point, int *end)
{
- const LineInfo *li;
- char *temp, **matches;
- const char *ctemp;
+ const TYPE(LineInfo) *li;
+ Char *temp;
+ char **matches;
+ const Char *ctemp;
size_t len;
int what_to_do = '\t';
int retval = CC_NORM;
@@ -423,45 +464,47 @@ fn_complete(EditLine *el,
app_func = append_char_function;
/* We now look backwards for the start of a filename/variable word */
- li = el_line(el);
- ctemp = (const char *) li->cursor;
+ li = FUN(el,line)(el);
+ ctemp = li->cursor;
while (ctemp > li->buffer
- && !strchr(word_break, ctemp[-1])
- && (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) )
+ && !Strchr(word_break, ctemp[-1])
+ && (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
ctemp--;
- len = li->cursor - ctemp;
+ len = (size_t)(li->cursor - ctemp);
#if defined(__SSP__) || defined(__SSP_ALL__)
- temp = malloc(len + 1);
+ temp = el_malloc((len + 1) * sizeof(*temp));
#else
- temp = alloca(len + 1);
+ temp = alloca((len + 1) * sizeof(*temp));
#endif
- (void)strncpy(temp, ctemp, len);
+ (void)Strncpy(temp, ctemp, len);
temp[len] = '\0';
/* these can be used by function called in completion_matches() */
/* or (*attempted_completion_function)() */
if (point != 0)
- *point = li->cursor - li->buffer;
+ *point = (int)(li->cursor - li->buffer);
if (end != NULL)
- *end = li->lastchar - li->buffer;
+ *end = (int)(li->lastchar - li->buffer);
if (attempted_completion_function) {
- int cur_off = li->cursor - li->buffer;
- matches = (*attempted_completion_function) (temp,
- (int)(cur_off - len), cur_off);
+ int cur_off = (int)(li->cursor - li->buffer);
+ matches = (*attempted_completion_function)(
+ ct_encode_string(temp, &el->el_scratch),
+ cur_off - (int)len, cur_off);
} else
matches = 0;
if (!attempted_completion_function ||
(over != NULL && !*over && !matches))
- matches = completion_matches(temp, complet_func);
+ matches = completion_matches(
+ ct_encode_string(temp, &el->el_scratch), complet_func);
if (over != NULL)
*over = 0;
if (matches) {
int i;
- int matches_num, maxlen, match_len, match_display=1;
+ size_t matches_num, maxlen, match_len, match_display=1;
retval = CC_REFRESH;
/*
@@ -470,7 +513,8 @@ fn_complete(EditLine *el,
*/
if (matches[0][0] != '\0') {
el_deletestr(el, (int) len);
- el_insertstr(el, matches[0]);
+ FUN(el,insertstr)(el,
+ ct_decode_string(matches[0], &el->el_scratch));
}
if (what_to_do == '?')
@@ -482,7 +526,9 @@ fn_complete(EditLine *el,
* it, unless we do filename completion and the
* object is a directory.
*/
- el_insertstr(el, (*app_func)(matches[0]));
+ FUN(el,insertstr)(el,
+ ct_decode_string((*app_func)(matches[0]),
+ &el->el_scratch));
} else if (what_to_do == '!') {
display_matches:
/*
@@ -490,12 +536,13 @@ fn_complete(EditLine *el,
* matches.
*/
- for(i=1, maxlen=0; matches[i]; i++) {
+ for(i = 1, maxlen = 0; matches[i]; i++) {
match_len = strlen(matches[i]);
if (match_len > maxlen)
maxlen = match_len;
}
- matches_num = i - 1;
+ /* matches[1] through matches[i-1] are available */
+ matches_num = (size_t)(i - 1);
/* newline to get on next line from command line */
(void)fprintf(el->el_outfile, "\n");
@@ -506,7 +553,7 @@ fn_complete(EditLine *el,
*/
if (matches_num > query_items) {
(void)fprintf(el->el_outfile,
- "Display all %d possibilities? (y or n) ",
+ "Display all %zu possibilities? (y or n) ",
matches_num);
(void)fflush(el->el_outfile);
if (getc(stdin) != 'y')
@@ -514,9 +561,17 @@ fn_complete(EditLine *el,
(void)fprintf(el->el_outfile, "\n");
}
- if (match_display)
- fn_display_match_list(el, matches, matches_num,
- maxlen);
+ if (match_display) {
+ /*
+ * Interface of this function requires the
+ * strings be matches[1..num-1] for compat.
+ * We have matches_num strings not counting
+ * the prefix in matches[0], so we need to
+ * add 1 to matches_num for the call.
+ */
+ fn_display_match_list(el, matches,
+ matches_num+1, maxlen);
+ }
retval = CC_REDISPLAY;
} else if (matches[0][0]) {
/*
@@ -534,12 +589,12 @@ fn_complete(EditLine *el,
/* free elements of array and the array itself */
for (i = 0; matches[i]; i++)
- free(matches[i]);
- free(matches);
+ el_free(matches[i]);
+ el_free(matches);
matches = NULL;
}
#if defined(__SSP__) || defined(__SSP_ALL__)
- free(temp);
+ el_free(temp);
#endif
return retval;
}
@@ -552,6 +607,6 @@ unsigned char
_el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
{
return (unsigned char)fn_complete(el, NULL, NULL,
- break_chars, NULL, NULL, 100,
+ break_chars, NULL, NULL, (size_t)100,
NULL, NULL, NULL, NULL);
}
diff --git a/cmd-line-utils/libedit/filecomplete.h b/cmd-line-utils/libedit/filecomplete.h
index 12e0c6f14b0..971e6e05939 100644
--- a/cmd-line-utils/libedit/filecomplete.h
+++ b/cmd-line-utils/libedit/filecomplete.h
@@ -1,4 +1,4 @@
-/* $NetBSD: filecomplete.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */
+/* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -34,10 +34,10 @@
int fn_complete(EditLine *,
char *(*)(const char *, int),
char **(*)(const char *, int, int),
- const char *, const char *, const char *(*)(const char *), int,
+ const Char *, const Char *, const char *(*)(const char *), size_t,
int *, int *, int *, int *);
-void fn_display_match_list(EditLine *, char **, int, int);
+void fn_display_match_list(EditLine *, char **, size_t, size_t);
char *fn_tilde_expand(const char *);
char *fn_filename_completion_function(const char *, int);
diff --git a/cmd-line-utils/libedit/hist.c b/cmd-line-utils/libedit/hist.c
index c0b23ee6641..d24f5e7ff53 100644
--- a/cmd-line-utils/libedit/hist.c
+++ b/cmd-line-utils/libedit/hist.c
@@ -1,4 +1,4 @@
-/* $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $ */
+/* $NetBSD: hist.c,v 1.20 2011/07/29 15:16:33 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -55,12 +55,12 @@ hist_init(EditLine *el)
el->el_history.fun = NULL;
el->el_history.ref = NULL;
- el->el_history.buf = (char *) el_malloc(EL_BUFSIZ);
+ el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf));
el->el_history.sz = EL_BUFSIZ;
if (el->el_history.buf == NULL)
- return (-1);
+ return -1;
el->el_history.last = el->el_history.buf;
- return (0);
+ return 0;
}
@@ -71,7 +71,7 @@ protected void
hist_end(EditLine *el)
{
- el_free((ptr_t) el->el_history.buf);
+ el_free(el->el_history.buf);
el->el_history.buf = NULL;
}
@@ -80,12 +80,12 @@ hist_end(EditLine *el)
* Set new history interface
*/
protected int
-hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
+hist_set(EditLine *el, hist_fun_t fun, void *ptr)
{
el->el_history.ref = ptr;
el->el_history.fun = fun;
- return (0);
+ return 0;
}
@@ -96,11 +96,11 @@ hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
protected el_action_t
hist_get(EditLine *el)
{
- const char *hp;
+ const Char *hp;
int h;
if (el->el_history.eventno == 0) { /* if really the current line */
- (void) strncpy(el->el_line.buffer, el->el_history.buf,
+ (void) Strncpy(el->el_line.buffer, el->el_history.buf,
el->el_history.sz);
el->el_line.lastchar = el->el_line.buffer +
(el->el_history.last - el->el_history.buf);
@@ -112,24 +112,25 @@ hist_get(EditLine *el)
#endif /* KSHVI */
el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
if (el->el_history.ref == NULL)
- return (CC_ERROR);
+ return CC_ERROR;
hp = HIST_FIRST(el);
if (hp == NULL)
- return (CC_ERROR);
+ return CC_ERROR;
for (h = 1; h < el->el_history.eventno; h++)
if ((hp = HIST_NEXT(el)) == NULL) {
el->el_history.eventno = h;
- return (CC_ERROR);
+ return CC_ERROR;
}
- (void) strlcpy(el->el_line.buffer, hp,
+ (void) Strncpy(el->el_line.buffer, hp,
(size_t)(el->el_line.limit - el->el_line.buffer));
- el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer);
+ el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0';
+ el->el_line.lastchar = el->el_line.buffer + Strlen(el->el_line.buffer);
if (el->el_line.lastchar > el->el_line.buffer
&& el->el_line.lastchar[-1] == '\n')
@@ -144,7 +145,7 @@ hist_get(EditLine *el)
#endif /* KSHVI */
el->el_line.cursor = el->el_line.lastchar;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -152,34 +153,34 @@ hist_get(EditLine *el)
* process a history command
*/
protected int
-hist_command(EditLine *el, int argc, const char **argv)
+hist_command(EditLine *el, int argc, const Char **argv)
{
- const char *str;
+ const Char *str;
int num;
- HistEvent ev;
+ TYPE(HistEvent) ev;
if (el->el_history.ref == NULL)
- return (-1);
+ return -1;
- if (argc == 1 || strcmp(argv[1], "list") == 0) {
+ if (argc == 1 || Strcmp(argv[1], STR("list")) == 0) {
/* List history entries */
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
(void) fprintf(el->el_outfile, "%d %s",
- el->el_history.ev.num, str);
- return (0);
+ el->el_history.ev.num, ct_encode_string(str, &el->el_scratch));
+ return 0;
}
if (argc != 3)
- return (-1);
+ return -1;
- num = (int)strtol(argv[2], NULL, 0);
+ num = (int)Strtol(argv[2], NULL, 0);
- if (strcmp(argv[1], "size") == 0)
- return history(el->el_history.ref, &ev, H_SETSIZE, num);
+ if (Strcmp(argv[1], STR("size")) == 0)
+ return FUNW(history)(el->el_history.ref, &ev, H_SETSIZE, num);
- if (strcmp(argv[1], "unique") == 0)
- return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
+ if (Strcmp(argv[1], STR("unique")) == 0)
+ return FUNW(history)(el->el_history.ref, &ev, H_SETUNIQUE, num);
return -1;
}
@@ -192,13 +193,13 @@ protected int
/*ARGSUSED*/
hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
{
- char *newbuf;
+ Char *newbuf;
- newbuf = realloc(el->el_history.buf, newsz);
+ newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf));
if (!newbuf)
return 0;
- (void) memset(&newbuf[oldsz], '\0', newsz - oldsz);
+ (void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf));
el->el_history.last = newbuf +
(el->el_history.last - el->el_history.buf);
@@ -207,3 +208,15 @@ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
return 1;
}
+
+#ifdef WIDECHAR
+protected wchar_t *
+hist_convert(EditLine *el, int fn, void *arg)
+{
+ HistEventW ev;
+ if ((*(el)->el_history.fun)((el)->el_history.ref, &ev, fn, arg) == -1)
+ return NULL;
+ return ct_decode_string((const char *)(const void *)ev.str,
+ &el->el_scratch);
+}
+#endif
diff --git a/cmd-line-utils/libedit/hist.h b/cmd-line-utils/libedit/hist.h
index 46e14634adf..a63be499dbd 100644
--- a/cmd-line-utils/libedit/hist.h
+++ b/cmd-line-utils/libedit/hist.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $ */
+/* $NetBSD: hist.h,v 1.13 2011/07/28 20:50:55 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -42,21 +42,29 @@
#include "histedit.h"
-typedef int (*hist_fun_t)(ptr_t, HistEvent *, int, ...);
+typedef int (*hist_fun_t)(void *, TYPE(HistEvent) *, int, ...);
typedef struct el_history_t {
- char *buf; /* The history buffer */
+ Char *buf; /* The history buffer */
size_t sz; /* Size of history buffer */
- char *last; /* The last character */
+ Char *last; /* The last character */
int eventno; /* Event we are looking for */
- ptr_t ref; /* Argument for history fcns */
+ void * ref; /* Argument for history fcns */
hist_fun_t fun; /* Event access */
- HistEvent ev; /* Event cookie */
+ TYPE(HistEvent) ev; /* Event cookie */
} el_history_t;
-#define HIST_FUN(el, fn, arg) \
+#define HIST_FUN_INTERNAL(el, fn, arg) \
((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \
fn, arg)) == -1) ? NULL : (el)->el_history.ev.str)
+#ifdef WIDECHAR
+#define HIST_FUN(el, fn, arg) \
+ (((el)->el_flags & NARROW_HISTORY) ? hist_convert(el, fn, arg) : \
+ HIST_FUN_INTERNAL(el, fn, arg))
+#else
+#define HIST_FUN(el, fn, arg) HIST_FUN_INTERNAL(el, fn, arg)
+#endif
+
#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
@@ -69,8 +77,11 @@ typedef struct el_history_t {
protected int hist_init(EditLine *);
protected void hist_end(EditLine *);
protected el_action_t hist_get(EditLine *);
-protected int hist_set(EditLine *, hist_fun_t, ptr_t);
-protected int hist_command(EditLine *, int, const char **);
+protected int hist_set(EditLine *, hist_fun_t, void *);
+protected int hist_command(EditLine *, int, const Char **);
protected int hist_enlargebuf(EditLine *, size_t, size_t);
+#ifdef WIDECHAR
+protected wchar_t *hist_convert(EditLine *, int, void *);
+#endif
#endif /* _h_el_hist */
diff --git a/cmd-line-utils/libedit/histedit.h b/cmd-line-utils/libedit/histedit.h
index 37823141c06..523d27b0be2 100644
--- a/cmd-line-utils/libedit/histedit.h
+++ b/cmd-line-utils/libedit/histedit.h
@@ -1,4 +1,4 @@
-/* $NetBSD: histedit.h,v 1.35 2009/02/05 19:15:44 christos Exp $ */
+/* $NetBSD: histedit.h,v 1.48 2011/07/28 20:50:55 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -43,6 +43,13 @@
#define LIBEDIT_MAJOR 2
#define LIBEDIT_MINOR 11
+/* XXXMYSQL : stdint.h might not be available on older Solaris platforms. */
+#if defined(__sun) || defined(__sun__)
+#include <sys/inttypes.h>
+#else
+#include <stdint.h>
+#endif
+
#include <sys/types.h>
#include <stdio.h>
@@ -114,29 +121,46 @@ unsigned char _el_fn_complete(EditLine *, int);
/*
* el_set/el_get parameters
+ *
+ * When using el_wset/el_wget (as opposed to el_set/el_get):
+ * Char is wchar_t, otherwise it is char.
+ * prompt_func is el_wpfunc_t, otherwise it is el_pfunc_t .
+
+ * Prompt function prototypes are:
+ * typedef char *(*el_pfunct_t) (EditLine *);
+ * typedef wchar_t *(*el_wpfunct_t) (EditLine *);
+ *
+ * For operations that support set or set/get, the argument types listed are for
+ * the "set" operation. For "get", each listed type must be a pointer.
+ * E.g. EL_EDITMODE takes an int when set, but an int* when get.
+ *
+ * Operations that only support "get" have the correct argument types listed.
*/
-#define EL_PROMPT 0 /* , el_pfunc_t); */
-#define EL_TERMINAL 1 /* , const char *); */
-#define EL_EDITOR 2 /* , const char *); */
-#define EL_SIGNAL 3 /* , int); */
-#define EL_BIND 4 /* , const char *, ..., NULL); */
-#define EL_TELLTC 5 /* , const char *, ..., NULL); */
-#define EL_SETTC 6 /* , const char *, ..., NULL); */
-#define EL_ECHOTC 7 /* , const char *, ..., NULL); */
-#define EL_SETTY 8 /* , const char *, ..., NULL); */
-#define EL_ADDFN 9 /* , const char *, const char * */
- /* , el_func_t); */
-#define EL_HIST 10 /* , hist_fun_t, const char *); */
-#define EL_EDITMODE 11 /* , int); */
-#define EL_RPROMPT 12 /* , el_pfunc_t); */
-#define EL_GETCFN 13 /* , el_rfunc_t); */
-#define EL_CLIENTDATA 14 /* , void *); */
-#define EL_UNBUFFERED 15 /* , int); */
-#define EL_PREP_TERM 16 /* , int); */
-#define EL_GETTC 17 /* , const char *, ..., NULL); */
-#define EL_GETFP 18 /* , int, FILE **); */
-#define EL_SETFP 19 /* , int, FILE *); */
-#define EL_REFRESH 20 /* , void); */
+#define EL_PROMPT 0 /* , prompt_func); set/get */
+#define EL_TERMINAL 1 /* , const char *); set/get */
+#define EL_EDITOR 2 /* , const Char *); set/get */
+#define EL_SIGNAL 3 /* , int); set/get */
+#define EL_BIND 4 /* , const Char *, ..., NULL); set */
+#define EL_TELLTC 5 /* , const Char *, ..., NULL); set */
+#define EL_SETTC 6 /* , const Char *, ..., NULL); set */
+#define EL_ECHOTC 7 /* , const Char *, ..., NULL); set */
+#define EL_SETTY 8 /* , const Char *, ..., NULL); set */
+#define EL_ADDFN 9 /* , const Char *, const Char, set */
+ /* el_func_t); */
+#define EL_HIST 10 /* , hist_fun_t, const void *); set */
+#define EL_EDITMODE 11 /* , int); set/get */
+#define EL_RPROMPT 12 /* , prompt_func); set/get */
+#define EL_GETCFN 13 /* , el_rfunc_t); set/get */
+#define EL_CLIENTDATA 14 /* , void *); set/get */
+#define EL_UNBUFFERED 15 /* , int); set/get */
+#define EL_PREP_TERM 16 /* , int); set */
+#define EL_GETTC 17 /* , const Char *, ..., NULL); get */
+#define EL_GETFP 18 /* , int, FILE **); get */
+#define EL_SETFP 19 /* , int, FILE *); set */
+#define EL_REFRESH 20 /* , void); set */
+#define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */
+#define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */
+#define EL_RESIZE 23 /* , el_zfunc_t, void *); set */
#define EL_BUILTIN_GETCFN (NULL)
@@ -188,12 +212,12 @@ int history(History *, HistEvent *, int, ...);
#define H_NEXT 6 /* , void); */
#define H_CURR 8 /* , const int); */
#define H_SET 7 /* , int); */
-#define H_ADD 9 /* , const char *); */
-#define H_ENTER 10 /* , const char *); */
-#define H_APPEND 11 /* , const char *); */
+#define H_ADD 9 /* , const wchar_t *); */
+#define H_ENTER 10 /* , const wchar_t *); */
+#define H_APPEND 11 /* , const wchar_t *); */
#define H_END 12 /* , void); */
-#define H_NEXT_STR 13 /* , const char *); */
-#define H_PREV_STR 14 /* , const char *); */
+#define H_NEXT_STR 13 /* , const wchar_t *); */
+#define H_PREV_STR 14 /* , const wchar_t *); */
#define H_NEXT_EVENT 15 /* , const int); */
#define H_PREV_EVENT 16 /* , const int); */
#define H_LOAD 17 /* , const char *); */
@@ -202,6 +226,10 @@ int history(History *, HistEvent *, int, ...);
#define H_SETUNIQUE 20 /* , int); */
#define H_GETUNIQUE 21 /* , void); */
#define H_DEL 22 /* , int); */
+#define H_NEXT_EVDATA 23 /* , const int, histdata_t *); */
+#define H_DELDATA 24 /* , int, histdata_t *);*/
+#define H_REPLACE 25 /* , const char *, histdata_t); */
+
/*
@@ -221,6 +249,65 @@ int tok_line(Tokenizer *, const LineInfo *,
int tok_str(Tokenizer *, const char *,
int *, const char ***);
+/*
+ * Begin Wide Character Support
+ */
+
+/*
+ * Wide character versions
+ */
+
+/*
+ * ==== Editing ====
+ */
+typedef struct lineinfow {
+ const wchar_t *buffer;
+ const wchar_t *cursor;
+ const wchar_t *lastchar;
+} LineInfoW;
+
+const wchar_t *el_wgets(EditLine *, int *);
+int el_wgetc(EditLine *, wchar_t *);
+void el_wpush(EditLine *, const wchar_t *);
+
+int el_wparse(EditLine *, int, const wchar_t **);
+
+int el_wset(EditLine *, int, ...);
+int el_wget(EditLine *, int, ...);
+
+const LineInfoW *el_wline(EditLine *);
+int el_winsertstr(EditLine *, const wchar_t *);
+#define el_wdeletestr el_deletestr
+
+/*
+ * ==== History ====
+ */
+typedef struct histeventW {
+ int num;
+ const wchar_t *str;
+} HistEventW;
+
+typedef struct historyW HistoryW;
+
+HistoryW * history_winit(void);
+void history_wend(HistoryW *);
+
+int history_w(HistoryW *, HistEventW *, int, ...);
+
+/*
+ * ==== Tokenization ====
+ */
+typedef struct tokenizerW TokenizerW;
+
+/* Wide character tokenizer support */
+TokenizerW *tok_winit(const wchar_t *);
+void tok_wend(TokenizerW *);
+void tok_wreset(TokenizerW *);
+int tok_wline(TokenizerW *, const LineInfoW *,
+ int *, const wchar_t ***, int *, int *);
+int tok_wstr(TokenizerW *, const wchar_t *,
+ int *, const wchar_t ***);
+
#ifdef __cplusplus
}
#endif
diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c
index 3080dd231f6..6d2176c258b 100644
--- a/cmd-line-utils/libedit/history.c
+++ b/cmd-line-utils/libedit/history.c
@@ -1,4 +1,4 @@
-/* $NetBSD: history.c,v 1.33 2009/02/06 14:40:32 sketch Exp $ */
+/* $NetBSD: history.c,v 1.45 2011/07/29 23:44:44 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@ static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#endif /* not lint && not SCCSID */
/*
- * hist.c: History access functions
+ * hist.c: TYPE(History) access functions
*/
#include <string.h>
#include <stdlib.h>
@@ -56,14 +56,15 @@ static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
static const char hist_cookie[] = "_HiStOrY_V2_\n";
#include "histedit.h"
+#include "chartype.h"
-typedef int (*history_gfun_t)(ptr_t, HistEvent *);
-typedef int (*history_efun_t)(ptr_t, HistEvent *, const char *);
-typedef void (*history_vfun_t)(ptr_t, HistEvent *);
-typedef int (*history_sfun_t)(ptr_t, HistEvent *, const int);
+typedef int (*history_gfun_t)(void *, TYPE(HistEvent) *);
+typedef int (*history_efun_t)(void *, TYPE(HistEvent) *, const Char *);
+typedef void (*history_vfun_t)(void *, TYPE(HistEvent) *);
+typedef int (*history_sfun_t)(void *, TYPE(HistEvent) *, const int);
-struct history {
- ptr_t h_ref; /* Argument for history fcns */
+struct TYPE(history) {
+ void *h_ref; /* Argument for history fcns */
int h_ent; /* Last entry point for history */
history_gfun_t h_first; /* Get the first element */
history_gfun_t h_next; /* Get the next element */
@@ -88,29 +89,29 @@ struct history {
#define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str)
#define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n)
-#define h_strdup(a) strdup(a)
+#define h_strdup(a) Strdup(a)
#define h_malloc(a) malloc(a)
#define h_realloc(a, b) realloc((a), (b))
#define h_free(a) free(a)
typedef struct {
int num;
- char *str;
+ Char *str;
} HistEventPrivate;
-private int history_setsize(History *, HistEvent *, int);
-private int history_getsize(History *, HistEvent *);
-private int history_setunique(History *, HistEvent *, int);
-private int history_getunique(History *, HistEvent *);
-private int history_set_fun(History *, History *);
-private int history_load(History *, const char *);
-private int history_save(History *, const char *);
-private int history_prev_event(History *, HistEvent *, int);
-private int history_next_event(History *, HistEvent *, int);
-private int history_next_string(History *, HistEvent *, const char *);
-private int history_prev_string(History *, HistEvent *, const char *);
+private int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int);
+private int history_getsize(TYPE(History) *, TYPE(HistEvent) *);
+private int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int);
+private int history_getunique(TYPE(History) *, TYPE(HistEvent) *);
+private int history_set_fun(TYPE(History) *, TYPE(History) *);
+private int history_load(TYPE(History) *, const char *);
+private int history_save(TYPE(History) *, const char *);
+private int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int);
+private int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int);
+private int history_next_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
+private int history_prev_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
/***********************************************************************/
@@ -119,7 +120,8 @@ private int history_prev_string(History *, HistEvent *, const char *);
* Builtin- history implementation
*/
typedef struct hentry_t {
- HistEvent ev; /* What we return */
+ TYPE(HistEvent) ev; /* What we return */
+ void *data; /* data */
struct hentry_t *next; /* Next entry */
struct hentry_t *prev; /* Previous entry */
} hentry_t;
@@ -130,24 +132,27 @@ typedef struct history_t {
int max; /* Maximum number of events */
int cur; /* Current number of events */
int eventid; /* For generation of unique event id */
- int flags; /* History flags */
+ int flags; /* TYPE(History) flags */
#define H_UNIQUE 1 /* Store only unique elements */
} history_t;
-private int history_def_next(ptr_t, HistEvent *);
-private int history_def_first(ptr_t, HistEvent *);
-private int history_def_prev(ptr_t, HistEvent *);
-private int history_def_last(ptr_t, HistEvent *);
-private int history_def_curr(ptr_t, HistEvent *);
-private int history_def_set(ptr_t, HistEvent *, const int);
-private void history_def_clear(ptr_t, HistEvent *);
-private int history_def_enter(ptr_t, HistEvent *, const char *);
-private int history_def_add(ptr_t, HistEvent *, const char *);
-private int history_def_del(ptr_t, HistEvent *, const int);
-
-private int history_def_init(ptr_t *, HistEvent *, int);
-private int history_def_insert(history_t *, HistEvent *, const char *);
-private void history_def_delete(history_t *, HistEvent *, hentry_t *);
+private int history_def_next(void *, TYPE(HistEvent) *);
+private int history_def_first(void *, TYPE(HistEvent) *);
+private int history_def_prev(void *, TYPE(HistEvent) *);
+private int history_def_last(void *, TYPE(HistEvent) *);
+private int history_def_curr(void *, TYPE(HistEvent) *);
+private int history_def_set(void *, TYPE(HistEvent) *, const int);
+private void history_def_clear(void *, TYPE(HistEvent) *);
+private int history_def_enter(void *, TYPE(HistEvent) *, const Char *);
+private int history_def_add(void *, TYPE(HistEvent) *, const Char *);
+private int history_def_del(void *, TYPE(HistEvent) *, const int);
+
+private int history_def_init(void **, TYPE(HistEvent) *, int);
+private int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *);
+private void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *);
+
+private int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **);
+private int history_set_nth(void *, TYPE(HistEvent) *, int);
#define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
#define history_def_getsize(p) (((history_t *)p)->cur)
@@ -165,23 +170,23 @@ private void history_def_delete(history_t *, HistEvent *, hentry_t *);
}
/* error messages */
-static const char *const he_errlist[] = {
- "OK",
- "unknown error",
- "malloc() failed",
- "first event not found",
- "last event not found",
- "empty list",
- "no next event",
- "no previous event",
- "current event is invalid",
- "event not found",
- "can't read history from file",
- "can't write history",
- "required parameter(s) not supplied",
- "history size negative",
- "function not allowed with other history-functions-set the default",
- "bad parameters"
+static const Char *const he_errlist[] = {
+ STR("OK"),
+ STR("unknown error"),
+ STR("malloc() failed"),
+ STR("first event not found"),
+ STR("last event not found"),
+ STR("empty list"),
+ STR("no next event"),
+ STR("no previous event"),
+ STR("current event is invalid"),
+ STR("event not found"),
+ STR("can't read history from file"),
+ STR("can't write history"),
+ STR("required parameter(s) not supplied"),
+ STR("history size negative"),
+ STR("function not allowed with other history-functions-set the default"),
+ STR("bad parameters")
};
/* error codes */
#define _HE_OK 0
@@ -205,7 +210,7 @@ static const char *const he_errlist[] = {
* Default function to return the first event in the history.
*/
private int
-history_def_first(ptr_t p, HistEvent *ev)
+history_def_first(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@@ -214,10 +219,10 @@ history_def_first(ptr_t p, HistEvent *ev)
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_FIRST_NOTFOUND);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
@@ -225,7 +230,7 @@ history_def_first(ptr_t p, HistEvent *ev)
* Default function to return the last event in the history.
*/
private int
-history_def_last(ptr_t p, HistEvent *ev)
+history_def_last(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@@ -234,10 +239,10 @@ history_def_last(ptr_t p, HistEvent *ev)
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_LAST_NOTFOUND);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
@@ -245,24 +250,24 @@ history_def_last(ptr_t p, HistEvent *ev)
* Default function to return the next event in the history.
*/
private int
-history_def_next(ptr_t p, HistEvent *ev)
+history_def_next(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
if (h->cursor == &h->list) {
he_seterrev(ev, _HE_EMPTY_LIST);
- return (-1);
+ return -1;
}
if (h->cursor->next == &h->list) {
he_seterrev(ev, _HE_END_REACHED);
- return (-1);
+ return -1;
}
h->cursor = h->cursor->next;
*ev = h->cursor->ev;
- return (0);
+ return 0;
}
@@ -270,25 +275,25 @@ history_def_next(ptr_t p, HistEvent *ev)
* Default function to return the previous event in the history.
*/
private int
-history_def_prev(ptr_t p, HistEvent *ev)
+history_def_prev(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
if (h->cursor == &h->list) {
he_seterrev(ev,
(h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
- return (-1);
+ return -1;
}
if (h->cursor->prev == &h->list) {
he_seterrev(ev, _HE_START_REACHED);
- return (-1);
+ return -1;
}
h->cursor = h->cursor->prev;
*ev = h->cursor->ev;
- return (0);
+ return 0;
}
@@ -296,7 +301,7 @@ history_def_prev(ptr_t p, HistEvent *ev)
* Default function to return the current event in the history.
*/
private int
-history_def_curr(ptr_t p, HistEvent *ev)
+history_def_curr(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@@ -305,10 +310,10 @@ history_def_curr(ptr_t p, HistEvent *ev)
else {
he_seterrev(ev,
(h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
@@ -317,13 +322,13 @@ history_def_curr(ptr_t p, HistEvent *ev)
* given one.
*/
private int
-history_def_set(ptr_t p, HistEvent *ev, const int n)
+history_def_set(void *p, TYPE(HistEvent) *ev, const int n)
{
history_t *h = (history_t *) p;
if (h->cur == 0) {
he_seterrev(ev, _HE_EMPTY_LIST);
- return (-1);
+ return -1;
}
if (h->cursor == &h->list || h->cursor->ev.num != n) {
for (h->cursor = h->list.next; h->cursor != &h->list;
@@ -333,9 +338,34 @@ history_def_set(ptr_t p, HistEvent *ev, const int n)
}
if (h->cursor == &h->list) {
he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
+}
+
+
+/* history_set_nth():
+ * Default function to set the current event in the history to the
+ * n-th one.
+ */
+private int
+history_set_nth(void *p, TYPE(HistEvent) *ev, int n)
+{
+ history_t *h = (history_t *) p;
+
+ if (h->cur == 0) {
+ he_seterrev(ev, _HE_EMPTY_LIST);
+ return -1;
+ }
+ for (h->cursor = h->list.prev; h->cursor != &h->list;
+ h->cursor = h->cursor->prev)
+ if (n-- <= 0)
+ break;
+ if (h->cursor == &h->list) {
+ he_seterrev(ev, _HE_NOT_FOUND);
+ return -1;
+ }
+ return 0;
}
@@ -343,27 +373,46 @@ history_def_set(ptr_t p, HistEvent *ev, const int n)
* Append string to element
*/
private int
-history_def_add(ptr_t p, HistEvent *ev, const char *str)
+history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
size_t len;
- char *s;
+ Char *s;
HistEventPrivate *evp = (void *)&h->cursor->ev;
if (h->cursor == &h->list)
- return (history_def_enter(p, ev, str));
- len = strlen(evp->str) + strlen(str) + 1;
- s = (char *) h_malloc(len);
+ return history_def_enter(p, ev, str);
+ len = Strlen(evp->str) + Strlen(str) + 1;
+ s = h_malloc(len * sizeof(*s));
if (s == NULL) {
he_seterrev(ev, _HE_MALLOC_FAILED);
- return (-1);
+ return -1;
}
- (void) strlcpy(s, h->cursor->ev.str, len);
- (void) strlcat(s, str, len);
- h_free((ptr_t)evp->str);
+ (void) Strncpy(s, h->cursor->ev.str, len);
+ s[len - 1] = '\0';
+ (void) Strncat(s, str, len - Strlen(s) - 1);
+ h_free(evp->str);
evp->str = s;
*ev = h->cursor->ev;
- return (0);
+ return 0;
+}
+
+
+private int
+history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
+ int num, void **data)
+{
+ if (history_set_nth(h, ev, num) != 0)
+ return -1;
+ /* magic value to skip delete (just set to n-th history) */
+ if (data == (void **)-1)
+ return 0;
+ ev->str = Strdup(h->cursor->ev.str);
+ ev->num = h->cursor->ev.num;
+ if (data)
+ *data = h->cursor->data;
+ history_def_delete(h, ev, h->cursor);
+ return 0;
}
@@ -372,16 +421,16 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str)
*/
/* ARGSUSED */
private int
-history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)),
+history_def_del(void *p, TYPE(HistEvent) *ev __attribute__((__unused__)),
const int num)
{
history_t *h = (history_t *) p;
if (history_def_set(h, ev, num) != 0)
- return (-1);
- ev->str = strdup(h->cursor->ev.str);
+ return -1;
+ ev->str = Strdup(h->cursor->ev.str);
ev->num = h->cursor->ev.num;
history_def_delete(h, ev, h->cursor);
- return (0);
+ return 0;
}
@@ -391,16 +440,19 @@ history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)),
/* ARGSUSED */
private void
history_def_delete(history_t *h,
- HistEvent *ev __attribute__((__unused__)), hentry_t *hp)
+ TYPE(HistEvent) *ev __attribute__((__unused__)), hentry_t *hp)
{
HistEventPrivate *evp = (void *)&hp->ev;
if (hp == &h->list)
abort();
- if (h->cursor == hp)
+ if (h->cursor == hp) {
h->cursor = hp->prev;
+ if (h->cursor == &h->list)
+ h->cursor = hp->next;
+ }
hp->prev->next = hp->next;
hp->next->prev = hp->prev;
- h_free((ptr_t) evp->str);
+ h_free(evp->str);
h_free(hp);
h->cur--;
}
@@ -410,28 +462,31 @@ history_def_delete(history_t *h,
* Insert element with string str in the h list
*/
private int
-history_def_insert(history_t *h, HistEvent *ev, const char *str)
+history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str)
{
+ hentry_t *c;
- h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
- if (h->cursor == NULL)
+ c = h_malloc(sizeof(*c));
+ if (c == NULL)
goto oomem;
- if ((h->cursor->ev.str = h_strdup(str)) == NULL) {
- h_free((ptr_t)h->cursor);
+ if ((c->ev.str = h_strdup(str)) == NULL) {
+ h_free(c);
goto oomem;
}
- h->cursor->ev.num = ++h->eventid;
- h->cursor->next = h->list.next;
- h->cursor->prev = &h->list;
- h->list.next->prev = h->cursor;
- h->list.next = h->cursor;
+ c->data = NULL;
+ c->ev.num = ++h->eventid;
+ c->next = h->list.next;
+ c->prev = &h->list;
+ h->list.next->prev = c;
+ h->list.next = c;
h->cur++;
+ h->cursor = c;
- *ev = h->cursor->ev;
- return (0);
+ *ev = c->ev;
+ return 0;
oomem:
he_seterrev(ev, _HE_MALLOC_FAILED);
- return (-1);
+ return -1;
}
@@ -439,16 +494,16 @@ oomem:
* Default function to enter an item in the history
*/
private int
-history_def_enter(ptr_t p, HistEvent *ev, const char *str)
+history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list &&
- strcmp(h->list.next->ev.str, str) == 0)
- return (0);
+ Strcmp(h->list.next->ev.str, str) == 0)
+ return 0;
if (history_def_insert(h, ev, str) == -1)
- return (-1); /* error, keep error message */
+ return -1; /* error, keep error message */
/*
* Always keep at least one entry.
@@ -457,7 +512,7 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
while (h->cur > h->max && h->cur > 0)
history_def_delete(h, ev, h->list.prev);
- return (1);
+ return 1;
}
@@ -466,9 +521,9 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
*/
/* ARGSUSED */
private int
-history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
+history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n)
{
- history_t *h = (history_t *) h_malloc(sizeof(history_t));
+ history_t *h = (history_t *) h_malloc(sizeof(*h));
if (h == NULL)
return -1;
@@ -482,7 +537,7 @@ history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
h->list.ev.num = 0;
h->cursor = &h->list;
h->flags = 0;
- *p = (ptr_t) h;
+ *p = h;
return 0;
}
@@ -491,12 +546,13 @@ history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
* Default history cleanup function
*/
private void
-history_def_clear(ptr_t p, HistEvent *ev)
+history_def_clear(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
while (h->list.prev != &h->list)
history_def_delete(h, ev, h->list.prev);
+ h->cursor = &h->list;
h->eventid = 0;
h->cur = 0;
}
@@ -509,16 +565,16 @@ history_def_clear(ptr_t p, HistEvent *ev)
/* history_init():
* Initialization function.
*/
-public History *
-history_init(void)
+public TYPE(History) *
+FUN(history,init)(void)
{
- HistEvent ev;
- History *h = (History *) h_malloc(sizeof(History));
+ TYPE(HistEvent) ev;
+ TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(*h));
if (h == NULL)
return NULL;
if (history_def_init(&h->h_ref, &ev, 0) == -1) {
- h_free((ptr_t)h);
+ h_free(h);
return NULL;
}
h->h_ent = -1;
@@ -533,7 +589,7 @@ history_init(void)
h->h_add = history_def_add;
h->h_del = history_def_del;
- return (h);
+ return h;
}
@@ -541,9 +597,9 @@ history_init(void)
* clean up history;
*/
public void
-history_end(History *h)
+FUN(history,end)(TYPE(History) *h)
{
- HistEvent ev;
+ TYPE(HistEvent) ev;
if (h->h_next == history_def_next)
history_def_clear(h->h_ref, &ev);
@@ -557,19 +613,19 @@ history_end(History *h)
* Set history number of events
*/
private int
-history_setsize(History *h, HistEvent *ev, int num)
+history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
- return (-1);
+ return -1;
}
if (num < 0) {
he_seterrev(ev, _HE_BAD_PARAM);
- return (-1);
+ return -1;
}
history_def_setsize(h->h_ref, num);
- return (0);
+ return 0;
}
@@ -577,18 +633,18 @@ history_setsize(History *h, HistEvent *ev, int num)
* Get number of events currently in history
*/
private int
-history_getsize(History *h, HistEvent *ev)
+history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
- return (-1);
+ return -1;
}
ev->num = history_def_getsize(h->h_ref);
if (ev->num < -1) {
he_seterrev(ev, _HE_SIZE_NEGATIVE);
- return (-1);
+ return -1;
}
- return (0);
+ return 0;
}
@@ -596,15 +652,15 @@ history_getsize(History *h, HistEvent *ev)
* Set if adjacent equal events should not be entered in history.
*/
private int
-history_setunique(History *h, HistEvent *ev, int uni)
+history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
- return (-1);
+ return -1;
}
history_def_setunique(h->h_ref, uni);
- return (0);
+ return 0;
}
@@ -612,14 +668,14 @@ history_setunique(History *h, HistEvent *ev, int uni)
* Get if adjacent equal events should not be entered in history.
*/
private int
-history_getunique(History *h, HistEvent *ev)
+history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
- return (-1);
+ return -1;
}
ev->num = history_def_getunique(h->h_ref);
- return (0);
+ return 0;
}
@@ -627,9 +683,9 @@ history_getunique(History *h, HistEvent *ev)
* Set history functions
*/
private int
-history_set_fun(History *h, History *nh)
+history_set_fun(TYPE(History) *h, TYPE(History) *nh)
{
- HistEvent ev;
+ TYPE(HistEvent) ev;
if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL ||
nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL ||
@@ -648,7 +704,7 @@ history_set_fun(History *h, History *nh)
h->h_add = history_def_add;
h->h_del = history_def_del;
}
- return (-1);
+ return -1;
}
if (h->h_next == history_def_next)
history_def_clear(h->h_ref, &ev);
@@ -665,25 +721,28 @@ history_set_fun(History *h, History *nh)
h->h_add = nh->h_add;
h->h_del = nh->h_del;
- return (0);
+ return 0;
}
/* history_load():
- * History load function
+ * TYPE(History) load function
*/
private int
-history_load(History *h, const char *fname)
+history_load(TYPE(History) *h, const char *fname)
{
FILE *fp;
char *line;
size_t sz, max_size;
char *ptr;
int i = -1;
- HistEvent ev;
+ TYPE(HistEvent) ev;
+#ifdef WIDECHAR
+ static ct_buffer_t conv;
+#endif
if ((fp = fopen(fname, "r")) == NULL)
- return (i);
+ return i;
if ((line = fgetln(fp, &sz)) == NULL)
goto done;
@@ -691,7 +750,7 @@ history_load(History *h, const char *fname)
if (strncmp(line, hist_cookie, sz) != 0)
goto done;
- ptr = h_malloc(max_size = 1024);
+ ptr = h_malloc((max_size = 1024) * sizeof(*ptr));
if (ptr == NULL)
goto done;
for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
@@ -704,8 +763,8 @@ history_load(History *h, const char *fname)
if (max_size < sz) {
char *nptr;
- max_size = (sz + 1024) & ~1023;
- nptr = h_realloc(ptr, max_size);
+ max_size = (sz + 1024) & (size_t)~1023;
+ nptr = h_realloc(ptr, max_size * sizeof(*ptr));
if (nptr == NULL) {
i = -1;
goto oomem;
@@ -714,63 +773,68 @@ history_load(History *h, const char *fname)
}
(void) strunvis(ptr, line);
line[sz] = c;
- if (HENTER(h, &ev, ptr) == -1) {
+ if (HENTER(h, &ev, ct_decode_string(ptr, &conv)) == -1) {
i = -1;
goto oomem;
}
}
oomem:
- h_free((ptr_t)ptr);
+ h_free(ptr);
done:
(void) fclose(fp);
- return (i);
+ return i;
}
/* history_save():
- * History save function
+ * TYPE(History) save function
*/
private int
-history_save(History *h, const char *fname)
+history_save(TYPE(History) *h, const char *fname)
{
FILE *fp;
- HistEvent ev;
+ TYPE(HistEvent) ev;
int i = -1, retval;
size_t len, max_size;
char *ptr;
+ const char *str;
+#ifdef WIDECHAR
+ static ct_buffer_t conv;
+#endif
if ((fp = fopen(fname, "w")) == NULL)
- return (-1);
+ return -1;
if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
goto done;
if (fputs(hist_cookie, fp) == EOF)
goto done;
- ptr = h_malloc(max_size = 1024);
+ ptr = h_malloc((max_size = 1024) * sizeof(*ptr));
if (ptr == NULL)
goto done;
for (i = 0, retval = HLAST(h, &ev);
retval != -1;
retval = HPREV(h, &ev), i++) {
- len = strlen(ev.str) * 4;
+ str = ct_encode_string(ev.str, &conv);
+ len = strlen(str) * 4;
if (len >= max_size) {
char *nptr;
- max_size = (len + 1024) & ~1023;
- nptr = h_realloc(ptr, max_size);
+ max_size = (len + 1024) & (size_t)~1023;
+ nptr = h_realloc(ptr, max_size * sizeof(*ptr));
if (nptr == NULL) {
i = -1;
goto oomem;
}
ptr = nptr;
}
- (void) strvis(ptr, ev.str, VIS_WHITE);
+ (void) strvis(ptr, str, VIS_WHITE);
(void) fprintf(fp, "%s\n", ptr);
}
oomem:
- h_free((ptr_t)ptr);
+ h_free(ptr);
done:
(void) fclose(fp);
- return (i);
+ return i;
}
@@ -778,16 +842,33 @@ done:
* Find the previous event, with number given
*/
private int
-history_prev_event(History *h, HistEvent *ev, int num)
+history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
if (ev->num == num)
- return (0);
+ return 0;
he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
+ return -1;
+}
+
+
+private int
+history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
+{
+ int retval;
+
+ for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
+ if (ev->num == num) {
+ if (d)
+ *d = ((history_t *)h->h_ref)->cursor->data;
+ return 0;
+ }
+
+ he_seterrev(ev, _HE_NOT_FOUND);
+ return -1;
}
@@ -795,16 +876,16 @@ history_prev_event(History *h, HistEvent *ev, int num)
* Find the next event, with number given
*/
private int
-history_next_event(History *h, HistEvent *ev, int num)
+history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
if (ev->num == num)
- return (0);
+ return 0;
he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
+ return -1;
}
@@ -812,17 +893,17 @@ history_next_event(History *h, HistEvent *ev, int num)
* Find the previous event beginning with string
*/
private int
-history_prev_string(History *h, HistEvent *ev, const char *str)
+history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
{
- size_t len = strlen(str);
+ size_t len = Strlen(str);
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
- if (strncmp(str, ev->str, len) == 0)
- return (0);
+ if (Strncmp(str, ev->str, len) == 0)
+ return 0;
he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
+ return -1;
}
@@ -830,17 +911,17 @@ history_prev_string(History *h, HistEvent *ev, const char *str)
* Find the next event beginning with string
*/
private int
-history_next_string(History *h, HistEvent *ev, const char *str)
+history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
{
- size_t len = strlen(str);
+ size_t len = Strlen(str);
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
- if (strncmp(str, ev->str, len) == 0)
- return (0);
+ if (Strncmp(str, ev->str, len) == 0)
+ return 0;
he_seterrev(ev, _HE_NOT_FOUND);
- return (-1);
+ return -1;
}
@@ -848,10 +929,10 @@ history_next_string(History *h, HistEvent *ev, const char *str)
* User interface to history functions.
*/
int
-history(History *h, HistEvent *ev, int fun, ...)
+FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...)
{
va_list va;
- const char *str;
+ const Char *str;
int retval;
va_start(va, fun);
@@ -876,7 +957,7 @@ history(History *h, HistEvent *ev, int fun, ...)
break;
case H_ADD:
- str = va_arg(va, const char *);
+ str = va_arg(va, const Char *);
retval = HADD(h, ev, str);
break;
@@ -885,13 +966,13 @@ history(History *h, HistEvent *ev, int fun, ...)
break;
case H_ENTER:
- str = va_arg(va, const char *);
+ str = va_arg(va, const Char *);
if ((retval = HENTER(h, ev, str)) != -1)
h->h_ent = ev->num;
break;
case H_APPEND:
- str = va_arg(va, const char *);
+ str = va_arg(va, const Char *);
if ((retval = HSET(h, ev, h->h_ent)) != -1)
retval = HADD(h, ev, str);
break;
@@ -946,18 +1027,18 @@ history(History *h, HistEvent *ev, int fun, ...)
break;
case H_PREV_STR:
- retval = history_prev_string(h, ev, va_arg(va, const char *));
+ retval = history_prev_string(h, ev, va_arg(va, const Char *));
break;
case H_NEXT_STR:
- retval = history_next_string(h, ev, va_arg(va, const char *));
+ retval = history_next_string(h, ev, va_arg(va, const Char *));
break;
case H_FUNC:
{
- History hf;
+ TYPE(History) hf;
- hf.h_ref = va_arg(va, ptr_t);
+ hf.h_ref = va_arg(va, void *);
h->h_ent = -1;
hf.h_first = va_arg(va, history_gfun_t);
hf.h_next = va_arg(va, history_gfun_t);
@@ -976,15 +1057,46 @@ history(History *h, HistEvent *ev, int fun, ...)
}
case H_END:
- history_end(h);
+ FUN(history,end)(h);
retval = 0;
break;
+ case H_NEXT_EVDATA:
+ {
+ int num = va_arg(va, int);
+ void **d = va_arg(va, void **);
+ retval = history_next_evdata(h, ev, num, d);
+ break;
+ }
+
+ case H_DELDATA:
+ {
+ int num = va_arg(va, int);
+ void **d = va_arg(va, void **);
+ retval = history_deldata_nth((history_t *)h->h_ref, ev, num, d);
+ break;
+ }
+
+ case H_REPLACE: /* only use after H_NEXT_EVDATA */
+ {
+ const Char *line = va_arg(va, const Char *);
+ void *d = va_arg(va, void *);
+ const Char *s;
+ if(!line || !(s = Strdup(line))) {
+ retval = -1;
+ break;
+ }
+ ((history_t *)h->h_ref)->cursor->ev.str = s;
+ ((history_t *)h->h_ref)->cursor->data = d;
+ retval = 0;
+ break;
+ }
+
default:
retval = -1;
he_seterrev(ev, _HE_UNKNOWN);
break;
}
va_end(va);
- return (retval);
+ return retval;
}
diff --git a/cmd-line-utils/libedit/historyn.c b/cmd-line-utils/libedit/historyn.c
new file mode 100644
index 00000000000..99871ea2075
--- /dev/null
+++ b/cmd-line-utils/libedit/historyn.c
@@ -0,0 +1,5 @@
+#define NARROW_WRAPPER
+#include "config.h"
+#undef WIDECHAR
+#define NARROWCHAR
+#include "./history.c"
diff --git a/cmd-line-utils/libedit/key.c b/cmd-line-utils/libedit/keymacro.c
index cda02816861..8df60e85d6c 100644
--- a/cmd-line-utils/libedit/key.c
+++ b/cmd-line-utils/libedit/keymacro.c
@@ -1,4 +1,4 @@
-/* $NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $ */
+/* $NetBSD: keymacro.c,v 1.7 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -41,20 +41,21 @@ static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#endif /* not lint && not SCCSID */
/*
- * key.c: This module contains the procedures for maintaining
- * the extended-key map.
+ * keymacro.c: This module contains the procedures for maintaining
+ * the extended-key map.
*
* An extended-key (key) is a sequence of keystrokes introduced
* with a sequence introducer and consisting of an arbitrary
- * number of characters. This module maintains a map (the el->el_key.map)
+ * number of characters. This module maintains a map (the
+ * el->el_keymacro.map)
* to convert these extended-key sequences into input strs
* (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE).
*
* Warning:
* If key is a substr of some other keys, then the longer
* keys are lost!! That is, if the keys "abcd" and "abcef"
- * are in el->el_key.map, adding the key "abc" will cause the first two
- * definitions to be lost.
+ * are in el->el_keymacro.map, adding the key "abc" will cause
+ * the first two definitions to be lost.
*
* Restrictions:
* -------------
@@ -67,102 +68,104 @@ static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#include "el.h"
/*
- * The Nodes of the el->el_key.map. The el->el_key.map is a linked list
- * of these node elements
+ * The Nodes of the el->el_keymacro.map. The el->el_keymacro.map is a
+ * linked list of these node elements
*/
-struct key_node_t {
- char ch; /* single character of key */
- int type; /* node type */
- key_value_t val; /* command code or pointer to str, */
+struct keymacro_node_t {
+ Char ch; /* single character of key */
+ int type; /* node type */
+ keymacro_value_t val; /* command code or pointer to str, */
/* if this is a leaf */
- struct key_node_t *next; /* ptr to next char of this key */
- struct key_node_t *sibling; /* ptr to another key with same prefix*/
+ struct keymacro_node_t *next; /* ptr to next char of this key */
+ struct keymacro_node_t *sibling;/* ptr to another key with same prefix*/
};
-private int node_trav(EditLine *, key_node_t *, char *,
- key_value_t *);
-private int node__try(EditLine *, key_node_t *, const char *,
- key_value_t *, int);
-private key_node_t *node__get(int);
-private void node__free(key_node_t *);
-private void node__put(EditLine *, key_node_t *);
-private int node__delete(EditLine *, key_node_t **, const char *);
-private int node_lookup(EditLine *, const char *, key_node_t *,
- int);
-private int node_enum(EditLine *, key_node_t *, int);
+private int node_trav(EditLine *, keymacro_node_t *, Char *,
+ keymacro_value_t *);
+private int node__try(EditLine *, keymacro_node_t *, const Char *,
+ keymacro_value_t *, int);
+private keymacro_node_t *node__get(Int);
+private void node__free(keymacro_node_t *);
+private void node__put(EditLine *, keymacro_node_t *);
+private int node__delete(EditLine *, keymacro_node_t **,
+ const Char *);
+private int node_lookup(EditLine *, const Char *,
+ keymacro_node_t *, size_t);
+private int node_enum(EditLine *, keymacro_node_t *, size_t);
#define KEY_BUFSIZ EL_BUFSIZ
-/* key_init():
+/* keymacro_init():
* Initialize the key maps
*/
protected int
-key_init(EditLine *el)
+keymacro_init(EditLine *el)
{
- el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ);
- if (el->el_key.buf == NULL)
- return (-1);
- el->el_key.map = NULL;
- key_reset(el);
- return (0);
+ el->el_keymacro.buf = el_malloc(KEY_BUFSIZ *
+ sizeof(*el->el_keymacro.buf));
+ if (el->el_keymacro.buf == NULL)
+ return -1;
+ el->el_keymacro.map = NULL;
+ keymacro_reset(el);
+ return 0;
}
-/* key_end():
+/* keymacro_end():
* Free the key maps
*/
protected void
-key_end(EditLine *el)
+keymacro_end(EditLine *el)
{
- el_free((ptr_t) el->el_key.buf);
- el->el_key.buf = NULL;
- node__free(el->el_key.map);
+ el_free(el->el_keymacro.buf);
+ el->el_keymacro.buf = NULL;
+ node__free(el->el_keymacro.map);
}
-/* key_map_cmd():
+/* keymacro_map_cmd():
* Associate cmd with a key value
*/
-protected key_value_t *
-key_map_cmd(EditLine *el, int cmd)
+protected keymacro_value_t *
+keymacro_map_cmd(EditLine *el, int cmd)
{
- el->el_key.val.cmd = (el_action_t) cmd;
- return (&el->el_key.val);
+ el->el_keymacro.val.cmd = (el_action_t) cmd;
+ return &el->el_keymacro.val;
}
-/* key_map_str():
+/* keymacro_map_str():
* Associate str with a key value
*/
-protected key_value_t *
-key_map_str(EditLine *el, char *str)
+protected keymacro_value_t *
+keymacro_map_str(EditLine *el, Char *str)
{
- el->el_key.val.str = str;
- return (&el->el_key.val);
+ el->el_keymacro.val.str = str;
+ return &el->el_keymacro.val;
}
-/* key_reset():
- * Takes all nodes on el->el_key.map and puts them on free list. Then
- * initializes el->el_key.map with arrow keys
+/* keymacro_reset():
+ * Takes all nodes on el->el_keymacro.map and puts them on free list.
+ * Then initializes el->el_keymacro.map with arrow keys
* [Always bind the ansi arrow keys?]
*/
protected void
-key_reset(EditLine *el)
+keymacro_reset(EditLine *el)
{
- node__put(el, el->el_key.map);
- el->el_key.map = NULL;
+ node__put(el, el->el_keymacro.map);
+ el->el_keymacro.map = NULL;
return;
}
-/* key_get():
- * Calls the recursive function with entry point el->el_key.map
+/* keymacro_get():
+ * Calls the recursive function with entry point el->el_keymacro.map
* Looks up *ch in map and then reads characters until a
* complete match is found or a mismatch occurs. Returns the
* type of the match found (XK_STR, XK_CMD, or XK_EXE).
@@ -170,98 +173,101 @@ key_reset(EditLine *el)
* The last character read is returned in *ch.
*/
protected int
-key_get(EditLine *el, char *ch, key_value_t *val)
+keymacro_get(EditLine *el, Char *ch, keymacro_value_t *val)
{
- return (node_trav(el, el->el_key.map, ch, val));
+ return node_trav(el, el->el_keymacro.map, ch, val);
}
-/* key_add():
- * Adds key to the el->el_key.map and associates the value in val with it.
- * If key is already is in el->el_key.map, the new code is applied to the
- * existing key. Ntype specifies if code is a command, an
- * out str or a unix command.
+/* keymacro_add():
+ * Adds key to the el->el_keymacro.map and associates the value in
+ * val with it. If key is already is in el->el_keymacro.map, the new
+ * code is applied to the existing key. Ntype specifies if code is a
+ * command, an out str or a unix command.
*/
protected void
-key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
+keymacro_add(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
{
if (key[0] == '\0') {
(void) fprintf(el->el_errfile,
- "key_add: Null extended-key not allowed.\n");
+ "keymacro_add: Null extended-key not allowed.\n");
return;
}
if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {
(void) fprintf(el->el_errfile,
- "key_add: sequence-lead-in command not allowed\n");
+ "keymacro_add: sequence-lead-in command not allowed\n");
return;
}
- if (el->el_key.map == NULL)
+ if (el->el_keymacro.map == NULL)
/* tree is initially empty. Set up new node to match key[0] */
- el->el_key.map = node__get(key[0]);
+ el->el_keymacro.map = node__get(key[0]);
/* it is properly initialized */
- /* Now recurse through el->el_key.map */
- (void) node__try(el, el->el_key.map, key, val, ntype);
+ /* Now recurse through el->el_keymacro.map */
+ (void) node__try(el, el->el_keymacro.map, key, val, ntype);
return;
}
-/* key_clear():
+/* keymacro_clear():
*
*/
protected void
-key_clear(EditLine *el, el_action_t *map, const char *in)
+keymacro_clear(EditLine *el, el_action_t *map, const Char *in)
{
-
+#ifdef WIDECHAR
+ if (*in > N_KEYS) /* can't be in the map */
+ return;
+#endif
if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
((map == el->el_map.key &&
el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
(map == el->el_map.alt &&
el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN)))
- (void) key_delete(el, in);
+ (void) keymacro_delete(el, in);
}
-/* key_delete():
+/* keymacro_delete():
* Delete the key and all longer keys staring with key, if
* they exists.
*/
protected int
-key_delete(EditLine *el, const char *key)
+keymacro_delete(EditLine *el, const Char *key)
{
if (key[0] == '\0') {
(void) fprintf(el->el_errfile,
- "key_delete: Null extended-key not allowed.\n");
- return (-1);
+ "keymacro_delete: Null extended-key not allowed.\n");
+ return -1;
}
- if (el->el_key.map == NULL)
- return (0);
+ if (el->el_keymacro.map == NULL)
+ return 0;
- (void) node__delete(el, &el->el_key.map, key);
- return (0);
+ (void) node__delete(el, &el->el_keymacro.map, key);
+ return 0;
}
-/* key_print():
+/* keymacro_print():
* Print the binding associated with key key.
- * Print entire el->el_key.map if null
+ * Print entire el->el_keymacro.map if null
*/
protected void
-key_print(EditLine *el, const char *key)
+keymacro_print(EditLine *el, const Char *key)
{
- /* do nothing if el->el_key.map is empty and null key specified */
- if (el->el_key.map == NULL && *key == 0)
+ /* do nothing if el->el_keymacro.map is empty and null key specified */
+ if (el->el_keymacro.map == NULL && *key == 0)
return;
- el->el_key.buf[0] = '"';
- if (node_lookup(el, key, el->el_key.map, 1) <= -1)
+ el->el_keymacro.buf[0] = '"';
+ if (node_lookup(el, key, el->el_keymacro.map, (size_t)1) <= -1)
/* key is not bound */
- (void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n",
- key);
+ (void) fprintf(el->el_errfile, "Unbound extended key \"" FSTR
+ "\"\n", key);
return;
}
@@ -271,34 +277,34 @@ key_print(EditLine *el, const char *key)
* found. May read in more characters.
*/
private int
-node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val)
+node_trav(EditLine *el, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val)
{
if (ptr->ch == *ch) {
/* match found */
if (ptr->next) {
/* key not complete so get next char */
- if (el_getc(el, ch) != 1) { /* if EOF or error */
+ if (FUN(el,getc)(el, ch) != 1) {/* if EOF or error */
val->cmd = ED_END_OF_FILE;
- return (XK_CMD);
+ return XK_CMD;
/* PWP: Pretend we just read an end-of-file */
}
- return (node_trav(el, ptr->next, ch, val));
+ return node_trav(el, ptr->next, ch, val);
} else {
*val = ptr->val;
if (ptr->type != XK_CMD)
*ch = '\0';
- return (ptr->type);
+ return ptr->type;
}
} else {
/* no match found here */
if (ptr->sibling) {
/* try next sibling */
- return (node_trav(el, ptr->sibling, ch, val));
+ return node_trav(el, ptr->sibling, ch, val);
} else {
/* no next sibling -- mismatch */
val->str = NULL;
- return (XK_STR);
+ return XK_STR;
}
}
}
@@ -308,11 +314,12 @@ node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val)
* Find a node that matches *str or allocate a new one
*/
private int
-node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int ntype)
+node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
+ keymacro_value_t *val, int ntype)
{
if (ptr->ch != *str) {
- key_node_t *xm;
+ keymacro_node_t *xm;
for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
if (xm->sibling->ch == *str)
@@ -335,7 +342,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
case XK_STR:
case XK_EXE:
if (ptr->val.str)
- el_free((ptr_t) ptr->val.str);
+ el_free(ptr->val.str);
break;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n",
@@ -349,7 +356,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
break;
case XK_STR:
case XK_EXE:
- if ((ptr->val.str = el_strdup(val->str)) == NULL)
+ if ((ptr->val.str = Strdup(val->str)) == NULL)
return -1;
break;
default:
@@ -362,7 +369,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
ptr->next = node__get(*str); /* setup new node */
(void) node__try(el, ptr->next, str, val, ntype);
}
- return (0);
+ return 0;
}
@@ -370,21 +377,21 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
* Delete node that matches str
*/
private int
-node__delete(EditLine *el, key_node_t **inptr, const char *str)
+node__delete(EditLine *el, keymacro_node_t **inptr, const Char *str)
{
- key_node_t *ptr;
- key_node_t *prev_ptr = NULL;
+ keymacro_node_t *ptr;
+ keymacro_node_t *prev_ptr = NULL;
ptr = *inptr;
if (ptr->ch != *str) {
- key_node_t *xm;
+ keymacro_node_t *xm;
for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
if (xm->sibling->ch == *str)
break;
if (xm->sibling == NULL)
- return (0);
+ return 0;
prev_ptr = xm;
ptr = xm->sibling;
}
@@ -396,20 +403,20 @@ node__delete(EditLine *el, key_node_t **inptr, const char *str)
prev_ptr->sibling = ptr->sibling;
ptr->sibling = NULL;
node__put(el, ptr);
- return (1);
+ return 1;
} else if (ptr->next != NULL &&
node__delete(el, &ptr->next, str) == 1) {
if (ptr->next != NULL)
- return (0);
+ return 0;
if (prev_ptr == NULL)
*inptr = ptr->sibling;
else
prev_ptr->sibling = ptr->sibling;
ptr->sibling = NULL;
node__put(el, ptr);
- return (1);
+ return 1;
} else {
- return (0);
+ return 0;
}
}
@@ -418,7 +425,7 @@ node__delete(EditLine *el, key_node_t **inptr, const char *str)
* Puts a tree of nodes onto free list using free(3).
*/
private void
-node__put(EditLine *el, key_node_t *ptr)
+node__put(EditLine *el, keymacro_node_t *ptr)
{
if (ptr == NULL)
return;
@@ -436,25 +443,25 @@ node__put(EditLine *el, key_node_t *ptr)
case XK_EXE:
case XK_STR:
if (ptr->val.str != NULL)
- el_free((ptr_t) ptr->val.str);
+ el_free(ptr->val.str);
break;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type));
break;
}
- el_free((ptr_t) ptr);
+ el_free(ptr);
}
/* node__get():
- * Returns pointer to a key_node_t for ch.
+ * Returns pointer to a keymacro_node_t for ch.
*/
-private key_node_t *
-node__get(int ch)
+private keymacro_node_t *
+node__get(Int ch)
{
- key_node_t *ptr;
+ keymacro_node_t *ptr;
- ptr = (key_node_t *) el_malloc((size_t) sizeof(key_node_t));
+ ptr = el_malloc(sizeof(*ptr));
if (ptr == NULL)
return NULL;
ptr->ch = ch;
@@ -462,17 +469,17 @@ node__get(int ch)
ptr->val.str = NULL;
ptr->next = NULL;
ptr->sibling = NULL;
- return (ptr);
+ return ptr;
}
private void
-node__free(key_node_t *k)
+node__free(keymacro_node_t *k)
{
if (k == NULL)
return;
node__free(k->sibling);
node__free(k->next);
- el_free((ptr_t) k);
+ el_free(k);
}
/* node_lookup():
@@ -480,37 +487,40 @@ node__free(key_node_t *k)
* Print if last node
*/
private int
-node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
+node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt)
{
- int ncnt;
+ ssize_t used;
if (ptr == NULL)
- return (-1); /* cannot have null ptr */
+ return -1; /* cannot have null ptr */
- if (*str == 0) {
+ if (!str || *str == 0) {
/* no more chars in str. node_enum from here. */
(void) node_enum(el, ptr, cnt);
- return (0);
+ return 0;
} else {
- /* If match put this char into el->el_key.buf. Recurse */
+ /* If match put this char into el->el_keymacro.buf. Recurse */
if (ptr->ch == *str) {
/* match found */
- ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt,
- (unsigned char) ptr->ch);
+ used = ct_visual_char(el->el_keymacro.buf + cnt,
+ KEY_BUFSIZ - cnt, ptr->ch);
+ if (used == -1)
+ return -1; /* ran out of buffer space */
if (ptr->next != NULL)
/* not yet at leaf */
return (node_lookup(el, str + 1, ptr->next,
- ncnt + 1));
+ (size_t)used + cnt));
else {
/* next node is null so key should be complete */
if (str[1] == 0) {
- el->el_key.buf[ncnt + 1] = '"';
- el->el_key.buf[ncnt + 2] = '\0';
- key_kprint(el, el->el_key.buf,
+ size_t px = cnt + (size_t)used;
+ el->el_keymacro.buf[px] = '"';
+ el->el_keymacro.buf[px + 1] = '\0';
+ keymacro_kprint(el, el->el_keymacro.buf,
&ptr->val, ptr->type);
- return (0);
+ return 0;
} else
- return (-1);
+ return -1;
/* mismatch -- str still has chars */
}
} else {
@@ -519,7 +529,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
return (node_lookup(el, str, ptr->sibling,
cnt));
else
- return (-1);
+ return -1;
}
}
}
@@ -529,68 +539,76 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
* Traverse the node printing the characters it is bound in buffer
*/
private int
-node_enum(EditLine *el, key_node_t *ptr, int cnt)
+node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt)
{
- int ncnt;
+ ssize_t used;
if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */
- el->el_key.buf[++cnt] = '"';
- el->el_key.buf[++cnt] = '\0';
+ el->el_keymacro.buf[++cnt] = '"';
+ el->el_keymacro.buf[++cnt] = '\0';
(void) fprintf(el->el_errfile,
"Some extended keys too long for internal print buffer");
- (void) fprintf(el->el_errfile, " \"%s...\"\n", el->el_key.buf);
- return (0);
+ (void) fprintf(el->el_errfile, " \"" FSTR "...\"\n",
+ el->el_keymacro.buf);
+ return 0;
}
if (ptr == NULL) {
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
"node_enum: BUG!! Null ptr passed\n!");
#endif
- return (-1);
+ return -1;
}
/* put this char at end of str */
- ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt,
- (unsigned char)ptr->ch);
+ used = ct_visual_char(el->el_keymacro.buf + cnt, KEY_BUFSIZ - cnt,
+ ptr->ch);
if (ptr->next == NULL) {
/* print this key and function */
- el->el_key.buf[ncnt + 1] = '"';
- el->el_key.buf[ncnt + 2] = '\0';
- key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
+ el->el_keymacro.buf[cnt + (size_t)used ] = '"';
+ el->el_keymacro.buf[cnt + (size_t)used + 1] = '\0';
+ keymacro_kprint(el, el->el_keymacro.buf, &ptr->val, ptr->type);
} else
- (void) node_enum(el, ptr->next, ncnt + 1);
+ (void) node_enum(el, ptr->next, cnt + (size_t)used);
/* go to sibling if there is one */
if (ptr->sibling)
(void) node_enum(el, ptr->sibling, cnt);
- return (0);
+ return 0;
}
-/* key_kprint():
+/* keymacro_kprint():
* Print the specified key and its associated
* function specified by val
*/
protected void
-key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
+keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
{
el_bindings_t *fp;
char unparsbuf[EL_BUFSIZ];
static const char fmt[] = "%-15s-> %s\n";
+ mbstate_t state;
+ memset(&state, 0, sizeof(mbstate_t));
if (val != NULL)
switch (ntype) {
case XK_STR:
case XK_EXE:
- (void) key__decode_str(val->str, unparsbuf,
+ (void) keymacro__decode_str(val->str, unparsbuf,
sizeof(unparsbuf),
ntype == XK_STR ? "\"\"" : "[]");
- (void) fprintf(el->el_outfile, fmt, key, unparsbuf);
+ (void) fprintf(el->el_outfile, fmt,
+ ct_encode_string(key, &el->el_scratch), unparsbuf);
break;
case XK_CMD:
for (fp = el->el_map.help; fp->name; fp++)
if (val->cmd == fp->func) {
+ memset(&state, 0, sizeof(mbstate_t));
+ wcsrtombs(unparsbuf, (const wchar_t **) &fp->name,
+ sizeof(unparsbuf), &state);
+ unparsbuf[sizeof(unparsbuf) -1] = '\0';
(void) fprintf(el->el_outfile, fmt,
- key, fp->name);
+ ct_encode_string(key, &el->el_scratch), unparsbuf);
break;
}
#ifdef DEBUG_KEY
@@ -605,7 +623,8 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
break;
}
else
- (void) fprintf(el->el_outfile, fmt, key, "no input");
+ (void) fprintf(el->el_outfile, fmt, ct_encode_string(key,
+ &el->el_scratch), "no input");
}
@@ -614,53 +633,17 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
*b++ = c; \
else \
b++
-/* key__decode_char():
- * Put a printable form of char in buf.
- */
-protected int
-key__decode_char(char *buf, int cnt, int off, int ch)
-{
- char *sb = buf + off;
- char *eb = buf + cnt;
- char *b = sb;
- if (ch == 0) {
- ADDC('^');
- ADDC('@');
- return b - sb;
- }
- if (iscntrl(ch)) {
- ADDC('^');
- if (ch == '\177')
- ADDC('?');
- else
- ADDC(ch | 0100);
- } else if (ch == '^') {
- ADDC('\\');
- ADDC('^');
- } else if (ch == '\\') {
- ADDC('\\');
- ADDC('\\');
- } else if (ch == ' ' || (el_isprint(ch) && !isspace(ch))) {
- ADDC(ch);
- } else {
- ADDC('\\');
- ADDC((((unsigned int) ch >> 6) & 7) + '0');
- ADDC((((unsigned int) ch >> 3) & 7) + '0');
- ADDC((ch & 7) + '0');
- }
- return b - sb;
-}
-
-
-/* key__decode_str():
+/* keymacro__decode_str():
* Make a printable version of the ey
*/
-protected int
-key__decode_str(const char *str, char *buf, int len, const char *sep)
+protected size_t
+keymacro__decode_str(const Char *str, char *buf, size_t len, const char *sep)
{
char *b = buf, *eb = b + len;
- const char *p;
+ const Char *p;
+ mbstate_t state;
+ memset(&state, 0, sizeof(mbstate_t));
b = buf;
if (sep[0] != '\0') {
ADDC(sep[0]);
@@ -668,38 +651,27 @@ key__decode_str(const char *str, char *buf, int len, const char *sep)
if (*str == '\0') {
ADDC('^');
ADDC('@');
- if (sep[0] != '\0' && sep[1] != '\0') {
- ADDC(sep[1]);
- }
- goto done;
+ goto add_endsep;
}
for (p = str; *p != 0; p++) {
- if (iscntrl((unsigned char) *p)) {
- ADDC('^');
- if (*p == '\177') {
- ADDC('?');
- } else {
- ADDC(*p | 0100);
- }
- } else if (*p == '^' || *p == '\\') {
- ADDC('\\');
- ADDC(*p);
- } else if (*p == ' ' || (el_isprint((unsigned char) *p) &&
- !isspace((unsigned char) *p))) {
- ADDC(*p);
- } else {
- ADDC('\\');
- ADDC((((unsigned int) *p >> 6) & 7) + '0');
- ADDC((((unsigned int) *p >> 3) & 7) + '0');
- ADDC((*p & 7) + '0');
+ Char dbuf[VISUAL_WIDTH_MAX];
+ Char *p2 = dbuf;
+ ssize_t l = ct_visual_char(dbuf, VISUAL_WIDTH_MAX, *p);
+ while (l-- > 0) {
+ ssize_t n = ct_encode_char(b, (size_t)(eb - b), *p2++,
+ &state);
+ if (n == -1) /* ran out of space */
+ goto add_endsep;
+ else
+ b += n;
}
}
+add_endsep:
if (sep[0] != '\0' && sep[1] != '\0') {
ADDC(sep[1]);
}
-done:
ADDC('\0');
- if (b - buf >= len)
+ if ((size_t)(b - buf) >= len)
buf[len - 1] = '\0';
- return b - buf;
+ return (size_t)(b - buf);
}
diff --git a/cmd-line-utils/libedit/key.h b/cmd-line-utils/libedit/keymacro.h
index 9c6844e6d99..2445de5a5bc 100644
--- a/cmd-line-utils/libedit/key.h
+++ b/cmd-line-utils/libedit/keymacro.h
@@ -1,4 +1,4 @@
-/* $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $ */
+/* $NetBSD: keymacro.h,v 1.2 2011/07/28 03:44:36 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -35,47 +35,42 @@
*/
/*
- * el.key.h: Key macro header
+ * el.keymacro.h: Key macro header
*/
-#ifndef _h_el_key
-#define _h_el_key
+#ifndef _h_el_keymacro
+#define _h_el_keymacro
-typedef union key_value_t {
+typedef union keymacro_value_t {
el_action_t cmd; /* If it is a command the # */
- char *str; /* If it is a string... */
-} key_value_t;
+ Char *str; /* If it is a string... */
+} keymacro_value_t;
-typedef struct key_node_t key_node_t;
+typedef struct keymacro_node_t keymacro_node_t;
-typedef struct el_key_t {
- char *buf; /* Key print buffer */
- key_node_t *map; /* Key map */
- key_value_t val; /* Local conversion buffer */
-} el_key_t;
+typedef struct el_keymacromacro_t {
+ Char *buf; /* Key print buffer */
+ keymacro_node_t *map; /* Key map */
+ keymacro_value_t val; /* Local conversion buffer */
+} el_keymacro_t;
#define XK_CMD 0
#define XK_STR 1
#define XK_NOD 2
#define XK_EXE 3
-#undef key_end
-#undef key_clear
-#undef key_print
-
-protected int key_init(EditLine *);
-protected void key_end(EditLine *);
-protected key_value_t *key_map_cmd(EditLine *, int);
-protected key_value_t *key_map_str(EditLine *, char *);
-protected void key_reset(EditLine *);
-protected int key_get(EditLine *, char *, key_value_t *);
-protected void key_add(EditLine *, const char *, key_value_t *, int);
-protected void key_clear(EditLine *, el_action_t *, const char *);
-protected int key_delete(EditLine *, const char *);
-protected void key_print(EditLine *, const char *);
-protected void key_kprint(EditLine *, const char *, key_value_t *,
+protected int keymacro_init(EditLine *);
+protected void keymacro_end(EditLine *);
+protected keymacro_value_t *keymacro_map_cmd(EditLine *, int);
+protected keymacro_value_t *keymacro_map_str(EditLine *, Char *);
+protected void keymacro_reset(EditLine *);
+protected int keymacro_get(EditLine *, Char *, keymacro_value_t *);
+protected void keymacro_add(EditLine *, const Char *, keymacro_value_t *, int);
+protected void keymacro_clear(EditLine *, el_action_t *, const Char *);
+protected int keymacro_delete(EditLine *, const Char *);
+protected void keymacro_print(EditLine *, const Char *);
+protected void keymacro_kprint(EditLine *, const Char *, keymacro_value_t *,
int);
-protected int key__decode_str(const char *, char *, int,
+protected size_t keymacro__decode_str(const Char *, char *, size_t,
const char *);
-protected int key__decode_char(char *, int, int, int);
-#endif /* _h_el_key */
+#endif /* _h_el_keymacro */
diff --git a/cmd-line-utils/libedit/makelist.sh b/cmd-line-utils/libedit/makelist.sh
index 5d25b4776c9..b1a28c32370 100644
--- a/cmd-line-utils/libedit/makelist.sh
+++ b/cmd-line-utils/libedit/makelist.sh
@@ -1,5 +1,5 @@
#!/bin/sh -
-# $NetBSD: makelist,v 1.11 2005/10/22 16:45:03 christos Exp $
+# $NetBSD: makelist,v 1.16 2010/04/18 21:17:05 christos Exp $
#
# Copyright (c) 1992, 1993
# The Regents of the University of California. All rights reserved.
@@ -36,7 +36,7 @@
# makelist.sh: Automatically generate header files...
AWK=@AWK@
-USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
+USAGE="Usage: $0 -n|-h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
if [ "x$1" = "x" ]
then
@@ -53,6 +53,14 @@ case $FLAG in
# generate foo.h file from foo.c
#
+-n)
+ cat << _EOF
+#undef WIDECHAR
+#define NARROWCHAR
+#include "${FILES}"
+_EOF
+ ;;
+
-h)
set - `echo $FILES | sed -e 's/\\./_/g'`
hdr="_h_`basename $1`"
@@ -70,7 +78,7 @@ case $FLAG in
# XXX: need a space between name and prototype so that -fc and -fh
# parsing is much easier
#
- printf("protected el_action_t\t%s (EditLine *, int);\n", name);
+ printf("protected el_action_t\t%s (EditLine *, Int);\n", name);
}
}
END {
@@ -85,6 +93,7 @@ case $FLAG in
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#include \"config.h\"\n#include \"el.h\"\n");
+ printf("#include \"chartype.h\"\n");
printf("private const struct el_bindings_t el_func_help[] = {\n");
low = "abcdefghijklmnopqrstuvwxyz_";
high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
@@ -106,18 +115,18 @@ case $FLAG in
fname = fname s;
}
- printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ",");
+ printf(" { %-30.30s %-30.30s\n","STR(\"" fname "\"),", uname ",");
ok = 1;
}
}
/^ \*/ {
if (ok) {
- printf(" \"");
+ printf(" STR(\"");
for (i = 2; i < NF; i++)
printf("%s ", $i);
- # XXXMYSQL: support CRLF
+ # XXXMYSQL: support CRLF
sub("\r", "", $i);
- printf("%s\" },\n", $i);
+ printf("%s\") },\n", $i);
ok = 0;
}
}
@@ -157,7 +166,7 @@ case $FLAG in
END {
printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count);
- printf("typedef el_action_t (*el_func_t)(EditLine *, int);");
+ printf("typedef el_action_t (*el_func_t)(EditLine *, Int);");
printf("\nprotected const el_func_t* func__get(void);\n");
printf("#endif /* _h_fcns_c */\n");
}'
diff --git a/cmd-line-utils/libedit/map.c b/cmd-line-utils/libedit/map.c
index 693b56c82ba..17b07391b69 100644
--- a/cmd-line-utils/libedit/map.c
+++ b/cmd-line-utils/libedit/map.c
@@ -1,4 +1,4 @@
-/* $NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $ */
+/* $NetBSD: map.c,v 1.30 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -46,10 +46,8 @@ static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#include <stdlib.h>
#include "el.h"
-#define N_KEYS 256
-
-private void map_print_key(EditLine *, el_action_t *, const char *);
-private void map_print_some_keys(EditLine *, el_action_t *, int, int);
+private void map_print_key(EditLine *, el_action_t *, const Char *);
+private void map_print_some_keys(EditLine *, el_action_t *, Int, Int);
private void map_print_all_keys(EditLine *);
private void map_init_nls(EditLine *);
private void map_init_meta(EditLine *);
@@ -904,26 +902,25 @@ map_init(EditLine *el)
EL_ABORT((el->errfile, "Vi insert map incorrect\n"));
#endif
- el->el_map.alt = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
+ el->el_map.alt = el_malloc(sizeof(*el->el_map.alt) * N_KEYS);
if (el->el_map.alt == NULL)
- return (-1);
- el->el_map.key = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
+ return -1;
+ el->el_map.key = el_malloc(sizeof(*el->el_map.key) * N_KEYS);
if (el->el_map.key == NULL)
- return (-1);
+ return -1;
el->el_map.emacs = el_map_emacs;
el->el_map.vic = el_map_vi_command;
el->el_map.vii = el_map_vi_insert;
- el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) *
- EL_NUM_FCNS);
+ el->el_map.help = el_malloc(sizeof(*el->el_map.help) * EL_NUM_FCNS);
if (el->el_map.help == NULL)
- return (-1);
+ return -1;
(void) memcpy(el->el_map.help, help__get(),
- sizeof(el_bindings_t) * EL_NUM_FCNS);
- el->el_map.func = (el_func_t *)el_malloc(sizeof(el_func_t) *
- EL_NUM_FCNS);
+ sizeof(*el->el_map.help) * EL_NUM_FCNS);
+ el->el_map.func = el_malloc(sizeof(*el->el_map.func) * EL_NUM_FCNS);
if (el->el_map.func == NULL)
- return (-1);
- memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS);
+ return -1;
+ memcpy(el->el_map.func, func__get(), sizeof(*el->el_map.func)
+ * EL_NUM_FCNS);
el->el_map.nfunc = EL_NUM_FCNS;
#ifdef VIDEFAULT
@@ -931,7 +928,7 @@ map_init(EditLine *el)
#else
map_init_emacs(el);
#endif /* VIDEFAULT */
- return (0);
+ return 0;
}
@@ -942,16 +939,16 @@ protected void
map_end(EditLine *el)
{
- el_free((ptr_t) el->el_map.alt);
+ el_free(el->el_map.alt);
el->el_map.alt = NULL;
- el_free((ptr_t) el->el_map.key);
+ el_free(el->el_map.key);
el->el_map.key = NULL;
el->el_map.emacs = NULL;
el->el_map.vic = NULL;
el->el_map.vii = NULL;
- el_free((ptr_t) el->el_map.help);
+ el_free(el->el_map.help);
el->el_map.help = NULL;
- el_free((ptr_t) el->el_map.func);
+ el_free(el->el_map.func);
el->el_map.func = NULL;
}
@@ -967,7 +964,7 @@ map_init_nls(EditLine *el)
el_action_t *map = el->el_map.key;
for (i = 0200; i <= 0377; i++)
- if (el_isprint(i))
+ if (Isprint(i))
map[i] = ED_INSERT;
}
@@ -978,7 +975,7 @@ map_init_nls(EditLine *el)
private void
map_init_meta(EditLine *el)
{
- char buf[3];
+ Char buf[3];
int i;
el_action_t *map = el->el_map.key;
el_action_t *alt = el->el_map.alt;
@@ -996,7 +993,7 @@ map_init_meta(EditLine *el)
} else
map = alt;
}
- buf[0] = (char) i;
+ buf[0] = (Char) i;
buf[2] = 0;
for (i = 0200; i <= 0377; i++)
switch (map[i]) {
@@ -1006,7 +1003,7 @@ map_init_meta(EditLine *el)
break;
default:
buf[1] = i & 0177;
- key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD);
+ keymacro_add(el, buf, keymacro_map_cmd(el, (int) map[i]), XK_CMD);
break;
}
map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN;
@@ -1028,7 +1025,7 @@ map_init_vi(EditLine *el)
el->el_map.type = MAP_VI;
el->el_map.current = el->el_map.key;
- key_reset(el);
+ keymacro_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = vii[i];
@@ -1039,7 +1036,7 @@ map_init_vi(EditLine *el)
map_init_nls(el);
tty_bind_char(el, 1);
- term_bind_arrow(el);
+ terminal_bind_arrow(el);
}
@@ -1050,14 +1047,14 @@ protected void
map_init_emacs(EditLine *el)
{
int i;
- char buf[3];
+ Char buf[3];
el_action_t *key = el->el_map.key;
el_action_t *alt = el->el_map.alt;
const el_action_t *emacs = el->el_map.emacs;
el->el_map.type = MAP_EMACS;
el->el_map.current = el->el_map.key;
- key_reset(el);
+ keymacro_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = emacs[i];
@@ -1070,10 +1067,10 @@ map_init_emacs(EditLine *el)
buf[0] = CONTROL('X');
buf[1] = CONTROL('X');
buf[2] = 0;
- key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
+ keymacro_add(el, buf, keymacro_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
tty_bind_char(el, 1);
- term_bind_arrow(el);
+ terminal_bind_arrow(el);
}
@@ -1081,18 +1078,18 @@ map_init_emacs(EditLine *el)
* Set the editor
*/
protected int
-map_set_editor(EditLine *el, char *editor)
+map_set_editor(EditLine *el, Char *editor)
{
- if (strcmp(editor, "emacs") == 0) {
+ if (Strcmp(editor, STR("emacs")) == 0) {
map_init_emacs(el);
- return (0);
+ return 0;
}
- if (strcmp(editor, "vi") == 0) {
+ if (Strcmp(editor, STR("vi")) == 0) {
map_init_vi(el);
- return (0);
+ return 0;
}
- return (-1);
+ return -1;
}
@@ -1100,20 +1097,20 @@ map_set_editor(EditLine *el, char *editor)
* Retrieve the editor
*/
protected int
-map_get_editor(EditLine *el, const char **editor)
+map_get_editor(EditLine *el, const Char **editor)
{
if (editor == NULL)
- return (-1);
+ return -1;
switch (el->el_map.type) {
case MAP_EMACS:
- *editor = "emacs";
- return (0);
+ *editor = STR("emacs");
+ return 0;
case MAP_VI:
- *editor = "vi";
- return (0);
+ *editor = STR("vi");
+ return 0;
}
- return (-1);
+ return -1;
}
@@ -1121,22 +1118,22 @@ map_get_editor(EditLine *el, const char **editor)
* Print the function description for 1 key
*/
private void
-map_print_key(EditLine *el, el_action_t *map, const char *in)
+map_print_key(EditLine *el, el_action_t *map, const Char *in)
{
char outbuf[EL_BUFSIZ];
el_bindings_t *bp, *ep;
if (in[0] == '\0' || in[1] == '\0') {
- (void) key__decode_str(in, outbuf, sizeof(outbuf), "");
+ (void) keymacro__decode_str(in, outbuf, sizeof(outbuf), "");
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
if (bp->func == map[(unsigned char) *in]) {
(void) fprintf(el->el_outfile,
- "%s\t->\t%s\n", outbuf, bp->name);
+ "%s\t->\t" FSTR "\n", outbuf, bp->name);
return;
}
} else
- key_print(el, in);
+ keymacro_print(el, in);
}
@@ -1144,10 +1141,10 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
* Print keys from first to last
*/
private void
-map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
+map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last)
{
el_bindings_t *bp, *ep;
- char firstbuf[2], lastbuf[2];
+ Char firstbuf[2], lastbuf[2];
char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
firstbuf[0] = first;
@@ -1156,7 +1153,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
lastbuf[1] = 0;
if (map[first] == ED_UNASSIGNED) {
if (first == last) {
- (void) key__decode_str(firstbuf, unparsbuf,
+ (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"%-15s-> is undefined\n", unparsbuf);
@@ -1167,17 +1164,17 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
for (bp = el->el_map.help; bp < ep; bp++) {
if (bp->func == map[first]) {
if (first == last) {
- (void) key__decode_str(firstbuf, unparsbuf,
+ (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
- (void) fprintf(el->el_outfile, "%-15s-> %s\n",
+ (void) fprintf(el->el_outfile, "%-15s-> " FSTR "\n",
unparsbuf, bp->name);
} else {
- (void) key__decode_str(firstbuf, unparsbuf,
+ (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
- (void) key__decode_str(lastbuf, extrabuf,
+ (void) keymacro__decode_str(lastbuf, extrabuf,
sizeof(extrabuf), STRQQ);
(void) fprintf(el->el_outfile,
- "%-4s to %-7s-> %s\n",
+ "%-4s to %-7s-> " FSTR "\n",
unparsbuf, extrabuf, bp->name);
}
return;
@@ -1185,14 +1182,14 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
}
#ifdef MAP_DEBUG
if (map == el->el_map.key) {
- (void) key__decode_str(firstbuf, unparsbuf,
+ (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf);
(void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n",
first, el->el_map.key[first]);
} else {
- (void) key__decode_str(firstbuf, unparsbuf,
+ (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf);
@@ -1233,9 +1230,9 @@ map_print_all_keys(EditLine *el)
map_print_some_keys(el, el->el_map.alt, prev, i - 1);
(void) fprintf(el->el_outfile, "Multi-character bindings\n");
- key_print(el, "");
+ keymacro_print(el, STR(""));
(void) fprintf(el->el_outfile, "Arrow key bindings\n");
- term_print_arrow(el, "");
+ terminal_print_arrow(el, STR(""));
}
@@ -1243,21 +1240,21 @@ map_print_all_keys(EditLine *el)
* Add/remove/change bindings
*/
protected int
-map_bind(EditLine *el, int argc, const char **argv)
+map_bind(EditLine *el, int argc, const Char **argv)
{
el_action_t *map;
int ntype, rem;
- const char *p;
- char inbuf[EL_BUFSIZ];
- char outbuf[EL_BUFSIZ];
- const char *in = NULL;
- char *out = NULL;
+ const Char *p;
+ Char inbuf[EL_BUFSIZ];
+ Char outbuf[EL_BUFSIZ];
+ const Char *in = NULL;
+ Char *out = NULL;
el_bindings_t *bp, *ep;
int cmd;
int key;
if (argv == NULL)
- return (-1);
+ return -1;
map = el->el_map.key;
ntype = XK_CMD;
@@ -1287,63 +1284,63 @@ map_bind(EditLine *el, int argc, const char **argv)
case 'v':
map_init_vi(el);
- return (0);
+ return 0;
case 'e':
map_init_emacs(el);
- return (0);
+ return 0;
case 'l':
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
(void) fprintf(el->el_outfile,
- "%s\n\t%s\n",
+ "" FSTR "\n\t" FSTR "\n",
bp->name, bp->description);
- return (0);
+ return 0;
default:
(void) fprintf(el->el_errfile,
- "%s: Invalid switch `%c'.\n",
- argv[0], p[1]);
+ "" FSTR ": Invalid switch `%c'.\n",
+ argv[0], (int) p[1]);
}
else
break;
if (argv[argc] == NULL) {
map_print_all_keys(el);
- return (0);
+ return 0;
}
if (key)
in = argv[argc++];
else if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
(void) fprintf(el->el_errfile,
- "%s: Invalid \\ or ^ in instring.\n",
+ "" FSTR ": Invalid \\ or ^ in instring.\n",
argv[0]);
- return (-1);
+ return -1;
}
if (rem) {
if (key) {
- (void) term_clear_arrow(el, in);
- return (-1);
+ (void) terminal_clear_arrow(el, in);
+ return -1;
}
if (in[1])
- (void) key_delete(el, in);
+ (void) keymacro_delete(el, in);
else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
- (void) key_delete(el, in);
+ (void) keymacro_delete(el, in);
else
map[(unsigned char) *in] = ED_UNASSIGNED;
- return (0);
+ return 0;
}
if (argv[argc] == NULL) {
if (key)
- term_print_arrow(el, in);
+ terminal_print_arrow(el, in);
else
map_print_key(el, map, in);
- return (0);
+ return 0;
}
#ifdef notyet
if (argv[argc + 1] != NULL) {
- bindkey_usage();
- return (-1);
+ bindkeymacro_usage();
+ return -1;
}
#endif
@@ -1352,31 +1349,32 @@ map_bind(EditLine *el, int argc, const char **argv)
case XK_EXE:
if ((out = parse__string(outbuf, argv[argc])) == NULL) {
(void) fprintf(el->el_errfile,
- "%s: Invalid \\ or ^ in outstring.\n", argv[0]);
- return (-1);
+ "" FSTR ": Invalid \\ or ^ in outstring.\n", argv[0]);
+ return -1;
}
if (key)
- term_set_arrow(el, in, key_map_str(el, out), ntype);
+ terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype);
else
- key_add(el, in, key_map_str(el, out), ntype);
+ keymacro_add(el, in, keymacro_map_str(el, out), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
break;
case XK_CMD:
if ((cmd = parse_cmd(el, argv[argc])) == -1) {
(void) fprintf(el->el_errfile,
- "%s: Invalid command `%s'.\n", argv[0], argv[argc]);
- return (-1);
+ "" FSTR ": Invalid command `" FSTR "'.\n",
+ argv[0], argv[argc]);
+ return -1;
}
if (key)
- term_set_arrow(el, in, key_map_str(el, out), ntype);
+ terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype);
else {
if (in[1]) {
- key_add(el, in, key_map_cmd(el, cmd), ntype);
+ keymacro_add(el, in, keymacro_map_cmd(el, cmd), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
} else {
- key_clear(el, map, in);
- map[(unsigned char) *in] = cmd;
+ keymacro_clear(el, map, in);
+ map[(unsigned char) *in] = (el_action_t)cmd;
}
}
break;
@@ -1385,7 +1383,7 @@ map_bind(EditLine *el, int argc, const char **argv)
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
break;
}
- return (0);
+ return 0;
}
@@ -1393,29 +1391,30 @@ map_bind(EditLine *el, int argc, const char **argv)
* add a user defined function
*/
protected int
-map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func)
+map_addfunc(EditLine *el, const Char *name, const Char *help, el_func_t func)
{
void *p;
- int nf = el->el_map.nfunc + 1;
+ size_t nf = (size_t)el->el_map.nfunc + 1;
if (name == NULL || help == NULL || func == NULL)
- return (-1);
+ return -1;
- if ((p = el_realloc(el->el_map.func, nf * sizeof(el_func_t))) == NULL)
- return (-1);
- el->el_map.func = (el_func_t *) p;
- if ((p = el_realloc(el->el_map.help, nf * sizeof(el_bindings_t)))
+ if ((p = el_realloc(el->el_map.func, nf *
+ sizeof(*el->el_map.func))) == NULL)
+ return -1;
+ el->el_map.func = p;
+ if ((p = el_realloc(el->el_map.help, nf * sizeof(*el->el_map.help)))
== NULL)
- return (-1);
- el->el_map.help = (el_bindings_t *) p;
+ return -1;
+ el->el_map.help = p;
- nf = el->el_map.nfunc;
+ nf = (size_t)el->el_map.nfunc;
el->el_map.func[nf] = func;
el->el_map.help[nf].name = name;
- el->el_map.help[nf].func = nf;
+ el->el_map.help[nf].func = (int)nf;
el->el_map.help[nf].description = help;
el->el_map.nfunc++;
- return (0);
+ return 0;
}
diff --git a/cmd-line-utils/libedit/map.h b/cmd-line-utils/libedit/map.h
index 3b08f48be7a..8e0c7e4eaa1 100644
--- a/cmd-line-utils/libedit/map.h
+++ b/cmd-line-utils/libedit/map.h
@@ -1,4 +1,4 @@
-/* $NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */
+/* $NetBSD: map.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -41,9 +41,9 @@
#define _h_el_map
typedef struct el_bindings_t { /* for the "bind" shell command */
- const char *name; /* function name for bind command */
+ const Char *name; /* function name for bind command */
int func; /* function numeric value */
- const char *description; /* description of function */
+ const Char *description; /* description of function */
} el_bindings_t;
@@ -63,13 +63,15 @@ typedef struct el_map_t {
#define MAP_EMACS 0
#define MAP_VI 1
-protected int map_bind(EditLine *, int, const char **);
+#define N_KEYS 256
+
+protected int map_bind(EditLine *, int, const Char **);
protected int map_init(EditLine *);
protected void map_end(EditLine *);
protected void map_init_vi(EditLine *);
protected void map_init_emacs(EditLine *);
-protected int map_set_editor(EditLine *, char *);
-protected int map_get_editor(EditLine *, const char **);
-protected int map_addfunc(EditLine *, const char *, const char *, el_func_t);
+protected int map_set_editor(EditLine *, Char *);
+protected int map_get_editor(EditLine *, const Char **);
+protected int map_addfunc(EditLine *, const Char *, const Char *, el_func_t);
#endif /* _h_el_map */
diff --git a/cmd-line-utils/libedit/np/strlcpy.c b/cmd-line-utils/libedit/np/strlcpy.c
index 092a9757c0f..ccbe6812dfc 100644
--- a/cmd-line-utils/libedit/np/strlcpy.c
+++ b/cmd-line-utils/libedit/np/strlcpy.c
@@ -23,6 +23,7 @@
#else
#include "config.h"
#endif
+
#if defined(LIBC_SCCS) && !defined(lint)
#endif /* LIBC_SCCS and not lint */
diff --git a/cmd-line-utils/libedit/np/unvis.c b/cmd-line-utils/libedit/np/unvis.c
index 3c37c231ceb..812d280b2d8 100644
--- a/cmd-line-utils/libedit/np/unvis.c
+++ b/cmd-line-utils/libedit/np/unvis.c
@@ -1,4 +1,4 @@
-/* $NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $ */
+/* $NetBSD: unvis.c,v 1.36 2011/03/18 09:07:20 martin Exp $ */
/*-
* Copyright (c) 1989, 1993
@@ -38,19 +38,33 @@ static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
#endif
#endif /* LIBC_SCCS and not lint */
+/* XXXMYSQL : Make compiler happy. */
+#ifdef _LIBC
+#include "namespace.h"
+#endif
+
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
-#include <stdio.h>
-#ifdef HAVE_VIS_H
-#include <vis.h>
+
+/* XXXMYSQL : stdint.h might not be available on older Solaris platforms. */
+#if defined(__sun) || defined(__sun__)
+#include <sys/inttypes.h>
#else
-#include "np/vis.h"
+#include <stdint.h>
#endif
+#include <stdio.h>
+#include <errno.h>
+/*
+ XXXMYSQL : Due to different versions of vis.h available,
+ use the one bundled with libedit.
+*/
+#include "np/vis.h"
+
#ifdef __weak_alias
-__weak_alias(strunvis,_strunvis)
+__weak_alias(strnunvisx,_strnunvisx)
#endif
#if !HAVE_VIS
@@ -64,143 +78,276 @@ __weak_alias(strunvis,_strunvis)
#define S_CTRL 4 /* control char started (^) */
#define S_OCTAL2 5 /* octal digit 2 */
#define S_OCTAL3 6 /* octal digit 3 */
-#define S_HEX1 7 /* hex digit */
-#define S_HEX2 8 /* hex digit 2 */
+#define S_HEX1 7 /* http hex digit */
+#define S_HEX2 8 /* http hex digit 2 */
+#define S_MIME1 9 /* mime hex digit 1 */
+#define S_MIME2 10 /* mime hex digit 2 */
+#define S_EATCRNL 11 /* mime eating CRNL */
+#define S_AMP 12 /* seen & */
+#define S_NUMBER 13 /* collecting number */
+#define S_STRING 14 /* collecting string */
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
+#define XTOD(c) (isdigit(c) ? (c - '0') : ((c - 'A') + 10))
+
+/*
+ * RFC 1866
+ */
+static const struct nv {
+ const char *name;
+ uint8_t value;
+} nv[] = {
+ { "AElig", 198 }, /* capital AE diphthong (ligature) */
+ { "Aacute", 193 }, /* capital A, acute accent */
+ { "Acirc", 194 }, /* capital A, circumflex accent */
+ { "Agrave", 192 }, /* capital A, grave accent */
+ { "Aring", 197 }, /* capital A, ring */
+ { "Atilde", 195 }, /* capital A, tilde */
+ { "Auml", 196 }, /* capital A, dieresis or umlaut mark */
+ { "Ccedil", 199 }, /* capital C, cedilla */
+ { "ETH", 208 }, /* capital Eth, Icelandic */
+ { "Eacute", 201 }, /* capital E, acute accent */
+ { "Ecirc", 202 }, /* capital E, circumflex accent */
+ { "Egrave", 200 }, /* capital E, grave accent */
+ { "Euml", 203 }, /* capital E, dieresis or umlaut mark */
+ { "Iacute", 205 }, /* capital I, acute accent */
+ { "Icirc", 206 }, /* capital I, circumflex accent */
+ { "Igrave", 204 }, /* capital I, grave accent */
+ { "Iuml", 207 }, /* capital I, dieresis or umlaut mark */
+ { "Ntilde", 209 }, /* capital N, tilde */
+ { "Oacute", 211 }, /* capital O, acute accent */
+ { "Ocirc", 212 }, /* capital O, circumflex accent */
+ { "Ograve", 210 }, /* capital O, grave accent */
+ { "Oslash", 216 }, /* capital O, slash */
+ { "Otilde", 213 }, /* capital O, tilde */
+ { "Ouml", 214 }, /* capital O, dieresis or umlaut mark */
+ { "THORN", 222 }, /* capital THORN, Icelandic */
+ { "Uacute", 218 }, /* capital U, acute accent */
+ { "Ucirc", 219 }, /* capital U, circumflex accent */
+ { "Ugrave", 217 }, /* capital U, grave accent */
+ { "Uuml", 220 }, /* capital U, dieresis or umlaut mark */
+ { "Yacute", 221 }, /* capital Y, acute accent */
+ { "aacute", 225 }, /* small a, acute accent */
+ { "acirc", 226 }, /* small a, circumflex accent */
+ { "acute", 180 }, /* acute accent */
+ { "aelig", 230 }, /* small ae diphthong (ligature) */
+ { "agrave", 224 }, /* small a, grave accent */
+ { "amp", 38 }, /* ampersand */
+ { "aring", 229 }, /* small a, ring */
+ { "atilde", 227 }, /* small a, tilde */
+ { "auml", 228 }, /* small a, dieresis or umlaut mark */
+ { "brvbar", 166 }, /* broken (vertical) bar */
+ { "ccedil", 231 }, /* small c, cedilla */
+ { "cedil", 184 }, /* cedilla */
+ { "cent", 162 }, /* cent sign */
+ { "copy", 169 }, /* copyright sign */
+ { "curren", 164 }, /* general currency sign */
+ { "deg", 176 }, /* degree sign */
+ { "divide", 247 }, /* divide sign */
+ { "eacute", 233 }, /* small e, acute accent */
+ { "ecirc", 234 }, /* small e, circumflex accent */
+ { "egrave", 232 }, /* small e, grave accent */
+ { "eth", 240 }, /* small eth, Icelandic */
+ { "euml", 235 }, /* small e, dieresis or umlaut mark */
+ { "frac12", 189 }, /* fraction one-half */
+ { "frac14", 188 }, /* fraction one-quarter */
+ { "frac34", 190 }, /* fraction three-quarters */
+ { "gt", 62 }, /* greater than */
+ { "iacute", 237 }, /* small i, acute accent */
+ { "icirc", 238 }, /* small i, circumflex accent */
+ { "iexcl", 161 }, /* inverted exclamation mark */
+ { "igrave", 236 }, /* small i, grave accent */
+ { "iquest", 191 }, /* inverted question mark */
+ { "iuml", 239 }, /* small i, dieresis or umlaut mark */
+ { "laquo", 171 }, /* angle quotation mark, left */
+ { "lt", 60 }, /* less than */
+ { "macr", 175 }, /* macron */
+ { "micro", 181 }, /* micro sign */
+ { "middot", 183 }, /* middle dot */
+ { "nbsp", 160 }, /* no-break space */
+ { "not", 172 }, /* not sign */
+ { "ntilde", 241 }, /* small n, tilde */
+ { "oacute", 243 }, /* small o, acute accent */
+ { "ocirc", 244 }, /* small o, circumflex accent */
+ { "ograve", 242 }, /* small o, grave accent */
+ { "ordf", 170 }, /* ordinal indicator, feminine */
+ { "ordm", 186 }, /* ordinal indicator, masculine */
+ { "oslash", 248 }, /* small o, slash */
+ { "otilde", 245 }, /* small o, tilde */
+ { "ouml", 246 }, /* small o, dieresis or umlaut mark */
+ { "para", 182 }, /* pilcrow (paragraph sign) */
+ { "plusmn", 177 }, /* plus-or-minus sign */
+ { "pound", 163 }, /* pound sterling sign */
+ { "quot", 34 }, /* double quote */
+ { "raquo", 187 }, /* angle quotation mark, right */
+ { "reg", 174 }, /* registered sign */
+ { "sect", 167 }, /* section sign */
+ { "shy", 173 }, /* soft hyphen */
+ { "sup1", 185 }, /* superscript one */
+ { "sup2", 178 }, /* superscript two */
+ { "sup3", 179 }, /* superscript three */
+ { "szlig", 223 }, /* small sharp s, German (sz ligature) */
+ { "thorn", 254 }, /* small thorn, Icelandic */
+ { "times", 215 }, /* multiply sign */
+ { "uacute", 250 }, /* small u, acute accent */
+ { "ucirc", 251 }, /* small u, circumflex accent */
+ { "ugrave", 249 }, /* small u, grave accent */
+ { "uml", 168 }, /* umlaut (dieresis) */
+ { "uuml", 252 }, /* small u, dieresis or umlaut mark */
+ { "yacute", 253 }, /* small y, acute accent */
+ { "yen", 165 }, /* yen sign */
+ { "yuml", 255 }, /* small y, dieresis or umlaut mark */
+};
/*
* unvis - decode characters previously encoded by vis
*/
int
-unvis(cp, c, astate, flag)
- char *cp;
- int c;
- int *astate, flag;
+unvis(char *cp, int c, int *astate, int flag)
{
unsigned char uc = (unsigned char)c;
+ unsigned char st, ia, is, lc;
+
+/*
+ * Bottom 8 bits of astate hold the state machine state.
+ * Top 8 bits hold the current character in the http 1866 nv string decoding
+ */
+#define GS(a) ((a) & 0xff)
+#define SS(a, b) (((uint32_t)(a) << 24) | (b))
+#define GI(a) ((uint32_t)(a) >> 24)
_DIAGASSERT(cp != NULL);
_DIAGASSERT(astate != NULL);
+ st = GS(*astate);
if (flag & UNVIS_END) {
- if (*astate == S_OCTAL2 || *astate == S_OCTAL3
- || *astate == S_HEX2) {
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ switch (st) {
+ case S_OCTAL2:
+ case S_OCTAL3:
+ case S_HEX2:
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
+ case S_GROUND:
+ return UNVIS_NOCHAR;
+ default:
+ return UNVIS_SYNBAD;
}
- return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
}
- switch (*astate) {
+ switch (st) {
case S_GROUND:
*cp = 0;
- if (c == '\\') {
- *astate = S_START;
- return (0);
+ if ((flag & VIS_NOESCAPE) == 0 && c == '\\') {
+ *astate = SS(0, S_START);
+ return UNVIS_NOCHAR;
+ }
+ if ((flag & VIS_HTTP1808) && c == '%') {
+ *astate = SS(0, S_HEX1);
+ return UNVIS_NOCHAR;
+ }
+ if ((flag & VIS_HTTP1866) && c == '&') {
+ *astate = SS(0, S_AMP);
+ return UNVIS_NOCHAR;
}
- if ((flag & VIS_HTTPSTYLE) && c == '%') {
- *astate = S_HEX1;
- return (0);
+ if ((flag & VIS_MIMESTYLE) && c == '=') {
+ *astate = SS(0, S_MIME1);
+ return UNVIS_NOCHAR;
}
*cp = c;
- return (UNVIS_VALID);
+ return UNVIS_VALID;
case S_START:
switch(c) {
case '\\':
*cp = c;
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
*cp = (c - '0');
- *astate = S_OCTAL2;
- return (0);
+ *astate = SS(0, S_OCTAL2);
+ return UNVIS_NOCHAR;
case 'M':
*cp = (char)0200;
- *astate = S_META;
- return (0);
+ *astate = SS(0, S_META);
+ return UNVIS_NOCHAR;
case '^':
- *astate = S_CTRL;
- return (0);
+ *astate = SS(0, S_CTRL);
+ return UNVIS_NOCHAR;
case 'n':
*cp = '\n';
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case 'r':
*cp = '\r';
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case 'b':
*cp = '\b';
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case 'a':
*cp = '\007';
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case 'v':
*cp = '\v';
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case 't':
*cp = '\t';
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case 'f':
*cp = '\f';
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case 's':
*cp = ' ';
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case 'E':
*cp = '\033';
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case '\n':
/*
* hidden newline
*/
- *astate = S_GROUND;
- return (UNVIS_NOCHAR);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_NOCHAR;
case '$':
/*
* hidden marker
*/
- *astate = S_GROUND;
- return (UNVIS_NOCHAR);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_NOCHAR;
}
- *astate = S_GROUND;
- return (UNVIS_SYNBAD);
+ goto bad;
case S_META:
if (c == '-')
- *astate = S_META1;
+ *astate = SS(0, S_META1);
else if (c == '^')
- *astate = S_CTRL;
- else {
- *astate = S_GROUND;
- return (UNVIS_SYNBAD);
- }
- return (0);
+ *astate = SS(0, S_CTRL);
+ else
+ goto bad;
+ return UNVIS_NOCHAR;
case S_META1:
- *astate = S_GROUND;
+ *astate = SS(0, S_GROUND);
*cp |= c;
- return (UNVIS_VALID);
+ return UNVIS_VALID;
case S_CTRL:
if (c == '?')
*cp |= 0177;
else
*cp |= c & 037;
- *astate = S_GROUND;
- return (UNVIS_VALID);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
case S_OCTAL2: /* second possible octal digit */
if (isoctal(uc)) {
@@ -208,102 +355,206 @@ unvis(cp, c, astate, flag)
* yes - and maybe a third
*/
*cp = (*cp << 3) + (c - '0');
- *astate = S_OCTAL3;
- return (0);
+ *astate = SS(0, S_OCTAL3);
+ return UNVIS_NOCHAR;
}
/*
* no - done with current sequence, push back passed char
*/
- *astate = S_GROUND;
- return (UNVIS_VALIDPUSH);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALIDPUSH;
case S_OCTAL3: /* third possible octal digit */
- *astate = S_GROUND;
+ *astate = SS(0, S_GROUND);
if (isoctal(uc)) {
*cp = (*cp << 3) + (c - '0');
- return (UNVIS_VALID);
+ return UNVIS_VALID;
}
/*
* we were done, push back passed char
*/
- return (UNVIS_VALIDPUSH);
+ return UNVIS_VALIDPUSH;
case S_HEX1:
if (isxdigit(uc)) {
*cp = xtod(uc);
- *astate = S_HEX2;
- return (0);
+ *astate = SS(0, S_HEX2);
+ return UNVIS_NOCHAR;
}
/*
* no - done with current sequence, push back passed char
*/
- *astate = S_GROUND;
- return (UNVIS_VALIDPUSH);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALIDPUSH;
case S_HEX2:
*astate = S_GROUND;
if (isxdigit(uc)) {
*cp = xtod(uc) | (*cp << 4);
- return (UNVIS_VALID);
+ return UNVIS_VALID;
+ }
+ return UNVIS_VALIDPUSH;
+
+ case S_MIME1:
+ if (uc == '\n' || uc == '\r') {
+ *astate = SS(0, S_EATCRNL);
+ return UNVIS_NOCHAR;
+ }
+ if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) {
+ *cp = XTOD(uc);
+ *astate = SS(0, S_MIME2);
+ return UNVIS_NOCHAR;
}
- return (UNVIS_VALIDPUSH);
+ goto bad;
+
+ case S_MIME2:
+ if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) {
+ *astate = SS(0, S_GROUND);
+ *cp = XTOD(uc) | (*cp << 4);
+ return UNVIS_VALID;
+ }
+ goto bad;
+
+ case S_EATCRNL:
+ switch (uc) {
+ case '\r':
+ case '\n':
+ return UNVIS_NOCHAR;
+ case '=':
+ *astate = SS(0, S_MIME1);
+ return UNVIS_NOCHAR;
+ default:
+ *cp = uc;
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
+ }
+
+ case S_AMP:
+ *cp = 0;
+ if (uc == '#') {
+ *astate = SS(0, S_NUMBER);
+ return UNVIS_NOCHAR;
+ }
+ *astate = SS(0, S_STRING);
+ /*FALLTHROUGH*/
+
+ case S_STRING:
+ ia = *cp; /* index in the array */
+ is = GI(*astate); /* index in the string */
+ lc = is == 0 ? 0 : nv[ia].name[is - 1]; /* last character */
+
+ if (uc == ';')
+ uc = '\0';
+
+ for (; ia < __arraycount(nv); ia++) {
+ if (is != 0 && nv[ia].name[is - 1] != lc)
+ goto bad;
+ if (nv[ia].name[is] == uc)
+ break;
+ }
+
+ if (ia == __arraycount(nv))
+ goto bad;
+
+ if (uc != 0) {
+ *cp = ia;
+ *astate = SS(is + 1, S_STRING);
+ return UNVIS_NOCHAR;
+ }
+
+ *cp = nv[ia].value;
+ *astate = SS(0, S_GROUND);
+ return UNVIS_VALID;
+
+ case S_NUMBER:
+ if (uc == ';')
+ return UNVIS_VALID;
+ if (!isdigit(uc))
+ goto bad;
+ *cp += (*cp * 10) + uc - '0';
+ return UNVIS_NOCHAR;
default:
+ bad:
/*
* decoder in unknown state - (probably uninitialized)
*/
- *astate = S_GROUND;
- return (UNVIS_SYNBAD);
+ *astate = SS(0, S_GROUND);
+ return UNVIS_SYNBAD;
}
}
/*
- * strunvis - decode src into dst
+ * strnunvisx - decode src into dst
*
* Number of chars decoded into dst is returned, -1 on error.
* Dst is null terminated.
*/
int
-strunvisx(dst, src, flag)
- char *dst;
- const char *src;
- int flag;
+strnunvisx(char *dst, size_t dlen, const char *src, int flag)
{
char c;
- char *start = dst;
+ char t, *start = dst;
int state = 0;
_DIAGASSERT(src != NULL);
_DIAGASSERT(dst != NULL);
+#define CHECKSPACE() \
+ do { \
+ if (dlen-- == 0) { \
+ errno = ENOSPC; \
+ return -1; \
+ } \
+ } while (/*CONSTCOND*/0)
while ((c = *src++) != '\0') {
again:
- switch (unvis(dst, c, &state, flag)) {
+ switch (unvis(&t, c, &state, flag)) {
case UNVIS_VALID:
- dst++;
+ CHECKSPACE();
+ *dst++ = t;
break;
case UNVIS_VALIDPUSH:
- dst++;
+ CHECKSPACE();
+ *dst++ = t;
goto again;
case 0:
case UNVIS_NOCHAR:
break;
+ case UNVIS_SYNBAD:
+ errno = EINVAL;
+ return -1;
default:
- return (-1);
+ _DIAGASSERT(0);
+ errno = EINVAL;
+ return -1;
}
}
- if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
- dst++;
+ if (unvis(&t, c, &state, UNVIS_END) == UNVIS_VALID) {
+ CHECKSPACE();
+ *dst++ = t;
+ }
+ CHECKSPACE();
*dst = '\0';
- return (dst - start);
+ return (int)(dst - start);
+}
+
+int
+strunvisx(char *dst, const char *src, int flag)
+{
+ return strnunvisx(dst, (size_t)~0, src, flag);
+}
+
+int
+strunvis(char *dst, const char *src)
+{
+ return strnunvisx(dst, (size_t)~0, src, 0);
}
int
-strunvis(dst, src)
- char *dst;
- const char *src;
+strnunvis(char *dst, size_t dlen, const char *src)
{
- return strunvisx(dst, src, 0);
+ return strnunvisx(dst, dlen, src, 0);
}
#endif
diff --git a/cmd-line-utils/libedit/np/vis.c b/cmd-line-utils/libedit/np/vis.c
index 2a746274681..d7cc37b4f47 100644
--- a/cmd-line-utils/libedit/np/vis.c
+++ b/cmd-line-utils/libedit/np/vis.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vis.c,v 1.38 2008/09/04 09:41:44 lukem Exp $ */
+/* $NetBSD: vis.c,v 1.44 2011/03/12 19:52:48 christos Exp $ */
/*-
* Copyright (c) 1989, 1993
@@ -60,23 +60,24 @@
#if defined(LIBC_SCCS) && !defined(lint)
#endif /* LIBC_SCCS and not lint */
+/* XXXMYSQL : Make compiler happy. */
+#ifdef _LIBC
+#include "namespace.h"
+#endif
+
#include <sys/types.h>
#include <assert.h>
-#ifdef HAVE_VIS_H
-#include <vis.h>
-#else
+/*
+ XXXMYSQL : Due to different versions of vis.h available,
+ use the one bundled with libedit.
+*/
#include "np/vis.h"
-#endif
+#include <errno.h>
#include <stdlib.h>
#ifdef __weak_alias
-__weak_alias(strsvis,_strsvis)
-__weak_alias(strsvisx,_strsvisx)
-__weak_alias(strvis,_strvis)
__weak_alias(strvisx,_strvisx)
-__weak_alias(svis,_svis)
-__weak_alias(vis,_vis)
#endif
#if !HAVE_VIS || !HAVE_SVIS
@@ -85,7 +86,7 @@ __weak_alias(vis,_vis)
#include <stdio.h>
#include <string.h>
-static char *do_svis(char *, int, int, int, const char *);
+static char *do_svis(char *, size_t *, int, int, int, const char *);
#undef BELL
#define BELL '\a'
@@ -94,6 +95,7 @@ static char *do_svis(char *, int, int, int, const char *);
#define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
#define issafe(c) (c == '\b' || c == BELL || c == '\r')
#define xtoa(c) "0123456789abcdef"[c]
+#define XTOA(c) "0123456789ABCDEF"[c]
#define MAXEXTRAS 5
@@ -120,14 +122,54 @@ do { \
* This is do_hvis, for HTTP style (RFC 1808)
*/
static char *
-do_hvis(char *dst, int c, int flag, int nextc, const char *extra)
+do_hvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{
- if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) {
+
+ if ((isascii(c) && isalnum(c))
+ /* safe */
+ || c == '$' || c == '-' || c == '_' || c == '.' || c == '+'
+ /* extra */
+ || c == '!' || c == '*' || c == '\'' || c == '(' || c == ')'
+ || c == ',') {
+ dst = do_svis(dst, dlen, c, flag, nextc, extra);
+ } else {
+ if (dlen) {
+ if (*dlen < 3)
+ return NULL;
+ *dlen -= 3;
+ }
*dst++ = '%';
*dst++ = xtoa(((unsigned int)c >> 4) & 0xf);
*dst++ = xtoa((unsigned int)c & 0xf);
+ }
+
+ return dst;
+}
+
+/*
+ * This is do_mvis, for Quoted-Printable MIME (RFC 2045)
+ * NB: No handling of long lines or CRLF.
+ */
+static char *
+do_mvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
+{
+ if ((c != '\n') &&
+ /* Space at the end of the line */
+ ((isspace(c) && (nextc == '\r' || nextc == '\n')) ||
+ /* Out of range */
+ (!isspace(c) && (c < 33 || (c > 60 && c < 62) || c > 126)) ||
+ /* Specific char to be escaped */
+ strchr("#$@[\\]^`{|}~", c) != NULL)) {
+ if (dlen) {
+ if (*dlen < 3)
+ return NULL;
+ *dlen -= 3;
+ }
+ *dst++ = '=';
+ *dst++ = XTOA(((unsigned int)c >> 4) & 0xf);
+ *dst++ = XTOA((unsigned int)c & 0xf);
} else {
- dst = do_svis(dst, c, flag, nextc, extra);
+ dst = do_svis(dst, dlen, c, flag, nextc, extra);
}
return dst;
}
@@ -142,16 +184,28 @@ do_hvis(char *dst, int c, int flag, int nextc, const char *extra)
* backslash-protected.
*/
static char *
-do_svis(char *dst, int c, int flag, int nextc, const char *extra)
+do_svis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{
int isextra;
+ size_t odlen = dlen ? *dlen : 0;
+
isextra = strchr(extra, c) != NULL;
+#define HAVE(x) \
+ do { \
+ if (dlen) { \
+ if (*dlen < (x)) \
+ goto out; \
+ *dlen -= (x); \
+ } \
+ } while (/*CONSTCOND*/0)
if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) ||
((flag & VIS_SAFE) && issafe(c)))) {
+ HAVE(1);
*dst++ = c;
return dst;
}
if (flag & VIS_CSTYLE) {
+ HAVE(2);
switch (c) {
case '\n':
*dst++ = '\\'; *dst++ = 'n';
@@ -180,6 +234,7 @@ do_svis(char *dst, int c, int flag, int nextc, const char *extra)
case '\0':
*dst++ = '\\'; *dst++ = '0';
if (isoctal(nextc)) {
+ HAVE(2);
*dst++ = '0';
*dst++ = '0';
}
@@ -189,57 +244,104 @@ do_svis(char *dst, int c, int flag, int nextc, const char *extra)
*dst++ = '\\'; *dst++ = c;
return dst;
}
+ if (dlen)
+ *dlen = odlen;
}
}
if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
+ HAVE(4);
*dst++ = '\\';
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0';
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0';
*dst++ = (c & 07) + '0';
} else {
- if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\';
+ if ((flag & VIS_NOSLASH) == 0) {
+ HAVE(1);
+ *dst++ = '\\';
+ }
+
if (c & 0200) {
+ HAVE(1);
c &= 0177; *dst++ = 'M';
}
+
if (iscntrl(c)) {
+ HAVE(2);
*dst++ = '^';
if (c == 0177)
*dst++ = '?';
else
*dst++ = c + '@';
} else {
+ HAVE(2);
*dst++ = '-'; *dst++ = c;
}
}
return dst;
+out:
+ *dlen = odlen;
+ return NULL;
}
+typedef char *(*visfun_t)(char *, size_t *, int, int, int, const char *);
+
+/*
+ * Return the appropriate encoding function depending on the flags given.
+ */
+static visfun_t
+getvisfun(int flag)
+{
+ if (flag & VIS_HTTPSTYLE)
+ return do_hvis;
+ if (flag & VIS_MIMESTYLE)
+ return do_mvis;
+ return do_svis;
+}
/*
- * svis - visually encode characters, also encoding the characters
+ * isnvis - visually encode characters, also encoding the characters
* pointed to by `extra'
*/
-char *
-svis(char *dst, int c, int flag, int nextc, const char *extra)
+static char *
+isnvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{
char *nextra = NULL;
+ visfun_t f;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra);
if (!nextra) {
+ if (dlen && *dlen == 0) {
+ errno = ENOSPC;
+ return NULL;
+ }
*dst = '\0'; /* can't create nextra, return "" */
return dst;
}
- if (flag & VIS_HTTPSTYLE)
- dst = do_hvis(dst, c, flag, nextc, nextra);
- else
- dst = do_svis(dst, c, flag, nextc, nextra);
+ f = getvisfun(flag);
+ dst = (*f)(dst, dlen, c, flag, nextc, nextra);
free(nextra);
+ if (dst == NULL || (dlen && *dlen == 0)) {
+ errno = ENOSPC;
+ return NULL;
+ }
*dst = '\0';
return dst;
}
+char *
+svis(char *dst, int c, int flag, int nextc, const char *extra)
+{
+ return isnvis(dst, NULL, c, flag, nextc, extra);
+}
+
+char *
+snvis(char *dst, size_t dlen, int c, int flag, int nextc, const char *extra)
+{
+ return isnvis(dst, &dlen, c, flag, nextc, extra);
+}
+
/*
* strsvis, strsvisx - visually encode characters from src into dst
@@ -256,13 +358,14 @@ svis(char *dst, int c, int flag, int nextc, const char *extra)
* Strsvisx encodes exactly len bytes from src into dst.
* This is useful for encoding a block of data.
*/
-int
-strsvis(char *dst, const char *csrc, int flag, const char *extra)
+static int
+istrsnvis(char *dst, size_t *dlen, const char *csrc, int flag, const char *extra)
{
int c;
char *start;
char *nextra = NULL;
const unsigned char *src = (const unsigned char *)csrc;
+ visfun_t f;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
@@ -272,52 +375,87 @@ strsvis(char *dst, const char *csrc, int flag, const char *extra)
*dst = '\0'; /* can't create nextra, return "" */
return 0;
}
- if (flag & VIS_HTTPSTYLE) {
- for (start = dst; (c = *src++) != '\0'; /* empty */)
- dst = do_hvis(dst, c, flag, *src, nextra);
- } else {
- for (start = dst; (c = *src++) != '\0'; /* empty */)
- dst = do_svis(dst, c, flag, *src, nextra);
+ f = getvisfun(flag);
+ for (start = dst; (c = *src++) != '\0'; /* empty */) {
+ dst = (*f)(dst, dlen, c, flag, *src, nextra);
+ if (dst == NULL) {
+ errno = ENOSPC;
+ return -1;
+ }
}
free(nextra);
+ if (dlen && *dlen == 0) {
+ errno = ENOSPC;
+ return -1;
+ }
*dst = '\0';
- return (dst - start);
+ return (int)(dst - start);
}
+int
+strsvis(char *dst, const char *csrc, int flag, const char *extra)
+{
+ return istrsnvis(dst, NULL, csrc, flag, extra);
+}
int
-strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
+strsnvis(char *dst, size_t dlen, const char *csrc, int flag, const char *extra)
+{
+ return istrsnvis(dst, &dlen, csrc, flag, extra);
+}
+
+static int
+istrsnvisx(char *dst, size_t *dlen, const char *csrc, size_t len, int flag,
+ const char *extra)
{
unsigned char c;
char *start;
char *nextra = NULL;
const unsigned char *src = (const unsigned char *)csrc;
+ visfun_t f;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra);
if (! nextra) {
+ if (dlen && *dlen == 0) {
+ errno = ENOSPC;
+ return -1;
+ }
*dst = '\0'; /* can't create nextra, return "" */
return 0;
}
- if (flag & VIS_HTTPSTYLE) {
- for (start = dst; len > 0; len--) {
- c = *src++;
- dst = do_hvis(dst, c, flag,
- len > 1 ? *src : '\0', nextra);
- }
- } else {
- for (start = dst; len > 0; len--) {
- c = *src++;
- dst = do_svis(dst, c, flag,
- len > 1 ? *src : '\0', nextra);
+ f = getvisfun(flag);
+ for (start = dst; len > 0; len--) {
+ c = *src++;
+ dst = (*f)(dst, dlen, c, flag, len > 1 ? *src : '\0', nextra);
+ if (dst == NULL) {
+ errno = ENOSPC;
+ return -1;
}
}
free(nextra);
+ if (dlen && *dlen == 0) {
+ errno = ENOSPC;
+ return -1;
+ }
*dst = '\0';
- return (dst - start);
+ return (int)(dst - start);
+}
+
+int
+strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
+{
+ return istrsnvisx(dst, NULL, csrc, len, flag, extra);
+}
+
+int
+strsnvisx(char *dst, size_t dlen, const char *csrc, size_t len, int flag,
+ const char *extra)
+{
+ return istrsnvisx(dst, &dlen, csrc, len, flag, extra);
}
#endif
@@ -325,28 +463,47 @@ strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
/*
* vis - visually encode characters
*/
-char *
-vis(char *dst, int c, int flag, int nextc)
+static char *
+invis(char *dst, size_t *dlen, int c, int flag, int nextc)
{
char *extra = NULL;
unsigned char uc = (unsigned char)c;
+ visfun_t f;
_DIAGASSERT(dst != NULL);
MAKEEXTRALIST(flag, extra, "");
if (! extra) {
+ if (dlen && *dlen == 0) {
+ errno = ENOSPC;
+ return NULL;
+ }
*dst = '\0'; /* can't create extra, return "" */
return dst;
}
- if (flag & VIS_HTTPSTYLE)
- dst = do_hvis(dst, uc, flag, nextc, extra);
- else
- dst = do_svis(dst, uc, flag, nextc, extra);
+ f = getvisfun(flag);
+ dst = (*f)(dst, dlen, uc, flag, nextc, extra);
free(extra);
+ if (dst == NULL || (dlen && *dlen == 0)) {
+ errno = ENOSPC;
+ return NULL;
+ }
*dst = '\0';
return dst;
}
+char *
+vis(char *dst, int c, int flag, int nextc)
+{
+ return invis(dst, NULL, c, flag, nextc);
+}
+
+char *
+nvis(char *dst, size_t dlen, int c, int flag, int nextc)
+{
+ return invis(dst, &dlen, c, flag, nextc);
+}
+
/*
* strvis, strvisx - visually encode characters from src into dst
@@ -358,36 +515,68 @@ vis(char *dst, int c, int flag, int nextc)
* Strvisx encodes exactly len bytes from src into dst.
* This is useful for encoding a block of data.
*/
-int
-strvis(char *dst, const char *src, int flag)
+static int
+istrnvis(char *dst, size_t *dlen, const char *src, int flag)
{
char *extra = NULL;
int rv;
MAKEEXTRALIST(flag, extra, "");
if (!extra) {
+ if (dlen && *dlen == 0) {
+ errno = ENOSPC;
+ return -1;
+ }
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
- rv = strsvis(dst, src, flag, extra);
+ rv = istrsnvis(dst, dlen, src, flag, extra);
free(extra);
return rv;
}
+int
+strvis(char *dst, const char *src, int flag)
+{
+ return istrnvis(dst, NULL, src, flag);
+}
int
-strvisx(char *dst, const char *src, size_t len, int flag)
+strnvis(char *dst, size_t dlen, const char *src, int flag)
+{
+ return istrnvis(dst, &dlen, src, flag);
+}
+
+static int
+istrnvisx(char *dst, size_t *dlen, const char *src, size_t len, int flag)
{
char *extra = NULL;
int rv;
MAKEEXTRALIST(flag, extra, "");
if (!extra) {
+ if (dlen && *dlen == 0) {
+ errno = ENOSPC;
+ return -1;
+ }
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
- rv = strsvisx(dst, src, len, flag, extra);
+ rv = istrsnvisx(dst, dlen, src, len, flag, extra);
free(extra);
return rv;
}
+
+int
+strvisx(char *dst, const char *src, size_t len, int flag)
+{
+ return istrnvisx(dst, NULL, src, len, flag);
+}
+
+int
+strnvisx(char *dst, size_t dlen, const char *src, size_t len, int flag)
+{
+ return istrnvisx(dst, &dlen, src, len, flag);
+}
+
#endif
diff --git a/cmd-line-utils/libedit/np/vis.h b/cmd-line-utils/libedit/np/vis.h
index 11f5b740e2d..54a76e9108f 100644
--- a/cmd-line-utils/libedit/np/vis.h
+++ b/cmd-line-utils/libedit/np/vis.h
@@ -1,4 +1,4 @@
-/* $NetBSD: vis.h,v 1.16 2005/09/13 01:44:32 christos Exp $ */
+/* $NetBSD: vis.h,v 1.19 2011/03/12 19:52:45 christos Exp $ */
/*-
* Copyright (c) 1990, 1993
@@ -39,24 +39,29 @@
/*
* to select alternate encoding format
*/
-#define VIS_OCTAL 0x01 /* use octal \ddd format */
-#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */
+#define VIS_OCTAL 0x001 /* use octal \ddd format */
+#define VIS_CSTYLE 0x002 /* use \[nrft0..] where appropiate */
/*
* to alter set of characters encoded (default is to encode all
* non-graphic except space, tab, and newline).
*/
-#define VIS_SP 0x04 /* also encode space */
-#define VIS_TAB 0x08 /* also encode tab */
-#define VIS_NL 0x10 /* also encode newline */
+#define VIS_SP 0x004 /* also encode space */
+#define VIS_TAB 0x008 /* also encode tab */
+#define VIS_NL 0x010 /* also encode newline */
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
-#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
+#define VIS_SAFE 0x020 /* only encode "unsafe" characters */
/*
* other
*/
-#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
-#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */
+#define VIS_NOSLASH 0x040 /* inhibit printing '\' */
+#define VIS_HTTP1808 0x080 /* http-style escape % hex hex */
+#define VIS_HTTPSTYLE 0x080 /* http-style escape % hex hex */
+#define VIS_MIMESTYLE 0x100 /* mime-style escape = HEX HEX */
+#define VIS_HTTP1866 0x200 /* http-style &#num; or &string; */
+#define VIS_NOESCAPE 0x400 /* don't decode `\' */
+#define _VIS_END 0x800 /* for unvis */
/*
* unvis return codes
@@ -70,18 +75,40 @@
/*
* unvis flags
*/
-#define UNVIS_END 1 /* no more characters */
+#define UNVIS_END _VIS_END /* no more characters */
+/* XXXMYSQL */
+#ifndef __RENAME
+#define __RENAME(x)
+#endif
__BEGIN_DECLS
char *vis(char *, int, int, int);
+char *nvis(char *, size_t, int, int, int);
+
char *svis(char *, int, int, int, const char *);
+char *snvis(char *, size_t, int, int, int, const char *);
+
int strvis(char *, const char *, int);
+int strnvis(char *, size_t, const char *, int);
+
int strsvis(char *, const char *, int, const char *);
+int strsnvis(char *, size_t, const char *, int, const char *);
+
int strvisx(char *, const char *, size_t, int);
+int strnvisx(char *, size_t, const char *, size_t, int);
+
int strsvisx(char *, const char *, size_t, int, const char *);
+int strsnvisx(char *, size_t, const char *, size_t, int, const char *);
+
int strunvis(char *, const char *);
+int strnunvis(char *, size_t, const char *);
+
int strunvisx(char *, const char *, int);
-int unvis(char *, int, int *, int);
+int strnunvisx(char *, size_t, const char *, int);
+
+#ifndef __LIBC12_SOURCE__
+int unvis(char *, int, int *, int) __RENAME(__unvis50);
+#endif
__END_DECLS
#endif /* !_VIS_H_ */
diff --git a/cmd-line-utils/libedit/np/wcsdup.c b/cmd-line-utils/libedit/np/wcsdup.c
new file mode 100644
index 00000000000..2a77375e0b7
--- /dev/null
+++ b/cmd-line-utils/libedit/np/wcsdup.c
@@ -0,0 +1,43 @@
+/* $NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $ */
+
+/*
+ * Copyright (C) 2006 Aleksey Cheusov
+ *
+ * This material is provided "as is", with absolutely no warranty expressed
+ * or implied. Any use is at your own risk.
+ *
+ * Permission to use or copy this software for any purpose is hereby granted
+ * without fee. Permission to modify the code and to distribute modified
+ * code is also granted without any restrictions.
+ */
+
+#ifndef HAVE_WCSDUP
+
+#include "config.h"
+
+#if defined(LIBC_SCCS) && !defined(lint)
+__RCSID("$NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $");
+#endif /* LIBC_SCCS and not lint */
+
+#include <stdlib.h>
+#include <assert.h>
+#include <wchar.h>
+
+wchar_t *
+wcsdup(const wchar_t *str)
+{
+ wchar_t *copy;
+ size_t len;
+
+ _DIAGASSERT(str != NULL);
+
+ len = wcslen(str) + 1;
+ copy = malloc(len * sizeof (wchar_t));
+
+ if (!copy)
+ return NULL;
+
+ return wmemcpy(copy, str, len);
+}
+
+#endif
diff --git a/cmd-line-utils/libedit/parse.c b/cmd-line-utils/libedit/parse.c
index 5bdefb5a0e4..b14e4ae7165 100644
--- a/cmd-line-utils/libedit/parse.c
+++ b/cmd-line-utils/libedit/parse.c
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $ */
+/* $NetBSD: parse.c,v 1.26 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -57,17 +57,17 @@ static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#include <stdlib.h>
private const struct {
- const char *name;
- int (*func)(EditLine *, int, const char **);
+ const Char *name;
+ int (*func)(EditLine *, int, const Char **);
} cmds[] = {
- { "bind", map_bind },
- { "echotc", term_echotc },
- { "edit", el_editmode },
- { "history", hist_command },
- { "telltc", term_telltc },
- { "settc", term_settc },
- { "setty", tty_stty },
- { NULL, NULL }
+ { STR("bind"), map_bind },
+ { STR("echotc"), terminal_echotc },
+ { STR("edit"), el_editmode },
+ { STR("history"), hist_command },
+ { STR("telltc"), terminal_telltc },
+ { STR("settc"), terminal_settc },
+ { STR("setty"), tty_stty },
+ { NULL, NULL }
};
@@ -75,17 +75,17 @@ private const struct {
* Parse a line and dispatch it
*/
protected int
-parse_line(EditLine *el, const char *line)
+parse_line(EditLine *el, const Char *line)
{
- const char **argv;
+ const Char **argv;
int argc;
- Tokenizer *tok;
+ TYPE(Tokenizer) *tok;
- tok = tok_init(NULL);
- tok_str(tok, line, &argc, &argv);
- argc = el_parse(el, argc, argv);
- tok_end(tok);
- return (argc);
+ tok = FUN(tok,init)(NULL);
+ FUN(tok,str)(tok, line, &argc, &argv);
+ argc = FUN(el,parse)(el, argc, argv);
+ FUN(tok,end)(tok);
+ return argc;
}
@@ -93,57 +93,57 @@ parse_line(EditLine *el, const char *line)
* Command dispatcher
*/
public int
-el_parse(EditLine *el, int argc, const char *argv[])
+FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
{
- const char *ptr;
+ const Char *ptr;
int i;
if (argc < 1)
- return (-1);
- ptr = strchr(argv[0], ':');
+ return -1;
+ ptr = Strchr(argv[0], ':');
if (ptr != NULL) {
- char *tprog;
+ Char *tprog;
size_t l;
if (ptr == argv[0])
- return (0);
- l = ptr - argv[0] - 1;
- tprog = (char *) el_malloc(l + 1);
+ return 0;
+ l = (size_t)(ptr - argv[0] - 1);
+ tprog = el_malloc((l + 1) * sizeof(*tprog));
if (tprog == NULL)
- return (0);
- (void) strncpy(tprog, argv[0], l);
+ return 0;
+ (void) Strncpy(tprog, argv[0], l);
tprog[l] = '\0';
ptr++;
- l = el_match(el->el_prog, tprog);
+ l = (size_t)el_match(el->el_prog, tprog);
el_free(tprog);
if (!l)
- return (0);
+ return 0;
} else
ptr = argv[0];
for (i = 0; cmds[i].name != NULL; i++)
- if (strcmp(cmds[i].name, ptr) == 0) {
+ if (Strcmp(cmds[i].name, ptr) == 0) {
i = (*cmds[i].func) (el, argc, argv);
- return (-i);
+ return -i;
}
- return (-1);
+ return -1;
}
/* parse__escape():
- * Parse a string of the form ^<char> \<odigit> \<char> and return
+ * Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
* the appropriate character or -1 if the escape is not valid
*/
protected int
-parse__escape(const char **ptr)
+parse__escape(const Char **ptr)
{
- const char *p;
- int c;
+ const Char *p;
+ Int c;
p = *ptr;
if (p[1] == 0)
- return (-1);
+ return -1;
if (*p == '\\') {
p++;
@@ -172,6 +172,28 @@ parse__escape(const char **ptr)
case 'e':
c = '\033'; /* Escape */
break;
+ case 'U': /* Unicode \U+xxxx or \U+xxxxx format */
+ {
+ int i;
+ const Char hex[] = STR("0123456789ABCDEF");
+ const Char *h;
+ ++p;
+ if (*p++ != '+')
+ return -1;
+ c = 0;
+ for (i = 0; i < 5; ++i) {
+ h = Strchr(hex, *p++);
+ if (!h && i < 4)
+ return -1;
+ else if (h)
+ c = (c << 4) | ((int)(h - hex));
+ else
+ --p;
+ }
+ if (c > 0x10FFFF) /* outside valid character range */
+ return -1;
+ break;
+ }
case '0':
case '1':
case '2':
@@ -191,8 +213,8 @@ parse__escape(const char **ptr)
}
c = (c << 3) | (ch - '0');
}
- if ((c & 0xffffff00) != 0)
- return (-1);
+ if ((c & (wint_t)0xffffff00) != (wint_t)0)
+ return -1;
--p;
break;
}
@@ -206,28 +228,28 @@ parse__escape(const char **ptr)
} else
c = *p;
*ptr = ++p;
- return (c);
+ return c;
}
/* parse__string():
* Parse the escapes from in and put the raw string out
*/
-protected char *
-parse__string(char *out, const char *in)
+protected Char *
+parse__string(Char *out, const Char *in)
{
- char *rv = out;
+ Char *rv = out;
int n;
for (;;)
switch (*in) {
case '\0':
*out = '\0';
- return (rv);
+ return rv;
case '\\':
case '^':
if ((n = parse__escape(&in)) == -1)
- return (NULL);
+ return NULL;
*out++ = n;
break;
@@ -251,12 +273,12 @@ parse__string(char *out, const char *in)
* or -1 if one is not found
*/
protected int
-parse_cmd(EditLine *el, const char *cmd)
+parse_cmd(EditLine *el, const Char *cmd)
{
el_bindings_t *b;
for (b = el->el_map.help; b->name != NULL; b++)
- if (strcmp(b->name, cmd) == 0)
- return (b->func);
- return (-1);
+ if (Strcmp(b->name, cmd) == 0)
+ return b->func;
+ return -1;
}
diff --git a/cmd-line-utils/libedit/parse.h b/cmd-line-utils/libedit/parse.h
index 58dced1aeaa..ec04051bc27 100644
--- a/cmd-line-utils/libedit/parse.h
+++ b/cmd-line-utils/libedit/parse.h
@@ -1,4 +1,4 @@
-/* $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $ */
+/* $NetBSD: parse.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,9 +40,9 @@
#ifndef _h_el_parse
#define _h_el_parse
-protected int parse_line(EditLine *, const char *);
-protected int parse__escape(const char **);
-protected char *parse__string(char *, const char *);
-protected int parse_cmd(EditLine *, const char *);
+protected int parse_line(EditLine *, const Char *);
+protected int parse__escape(const Char **);
+protected Char *parse__string(Char *, const Char *);
+protected int parse_cmd(EditLine *, const Char *);
#endif /* _h_el_parse */
diff --git a/cmd-line-utils/libedit/prompt.c b/cmd-line-utils/libedit/prompt.c
index 982943afd30..3f8d73303ec 100644
--- a/cmd-line-utils/libedit/prompt.c
+++ b/cmd-line-utils/libedit/prompt.c
@@ -1,4 +1,4 @@
-/* $NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $ */
+/* $NetBSD: prompt.c,v 1.20 2011/07/29 15:16:33 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -46,54 +46,66 @@ static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h>
#include "el.h"
-private char *prompt_default(EditLine *);
-private char *prompt_default_r(EditLine *);
+private Char *prompt_default(EditLine *);
+private Char *prompt_default_r(EditLine *);
/* prompt_default():
* Just a default prompt, in case the user did not provide one
*/
-private char *
+private Char *
/*ARGSUSED*/
prompt_default(EditLine *el __attribute__((__unused__)))
{
- static char a[3] = {'?', ' ', '\0'};
+ static Char a[3] = {'?', ' ', '\0'};
- return (a);
+ return a;
}
/* prompt_default_r():
* Just a default rprompt, in case the user did not provide one
*/
-private char *
+private Char *
/*ARGSUSED*/
prompt_default_r(EditLine *el __attribute__((__unused__)))
{
- static char a[1] = {'\0'};
+ static Char a[1] = {'\0'};
- return (a);
+ return a;
}
/* prompt_print():
* Print the prompt and update the prompt position.
- * We use an array of integers in case we want to pass
- * literal escape sequences in the prompt and we want a
- * bit to flag them
*/
protected void
prompt_print(EditLine *el, int op)
{
el_prompt_t *elp;
- char *p;
+ Char *p;
+ int ignore = 0;
if (op == EL_PROMPT)
elp = &el->el_prompt;
else
elp = &el->el_rprompt;
- p = (elp->p_func) (el);
- while (*p)
- re_putc(el, *p++, 1);
+
+ if (elp->p_wide)
+ p = (*elp->p_func)(el);
+ else
+ p = ct_decode_string((char *)(void *)(*elp->p_func)(el),
+ &el->el_scratch);
+
+ for (; *p; p++) {
+ if (elp->p_ignore == *p) {
+ ignore = !ignore;
+ continue;
+ }
+ if (ignore)
+ terminal__putc(el, *p);
+ else
+ re_putc(el, *p, 1);
+ }
elp->p_pos.v = el->el_refresh.r_cursor.v;
elp->p_pos.h = el->el_refresh.r_cursor.h;
@@ -110,10 +122,12 @@ prompt_init(EditLine *el)
el->el_prompt.p_func = prompt_default;
el->el_prompt.p_pos.v = 0;
el->el_prompt.p_pos.h = 0;
+ el->el_prompt.p_ignore = '\0';
el->el_rprompt.p_func = prompt_default_r;
el->el_rprompt.p_pos.v = 0;
el->el_rprompt.p_pos.h = 0;
- return (0);
+ el->el_rprompt.p_ignore = '\0';
+ return 0;
}
@@ -131,24 +145,31 @@ prompt_end(EditLine *el __attribute__((__unused__)))
* Install a prompt printing function
*/
protected int
-prompt_set(EditLine *el, el_pfunc_t prf, int op)
+prompt_set(EditLine *el, el_pfunc_t prf, Char c, int op, int wide)
{
el_prompt_t *p;
- if (op == EL_PROMPT)
+ if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p = &el->el_prompt;
else
p = &el->el_rprompt;
+
if (prf == NULL) {
- if (op == EL_PROMPT)
+ if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p->p_func = prompt_default;
else
p->p_func = prompt_default_r;
- } else
+ } else {
p->p_func = prf;
+ }
+
+ p->p_ignore = c;
+
p->p_pos.v = 0;
p->p_pos.h = 0;
- return (0);
+ p->p_wide = wide;
+
+ return 0;
}
@@ -156,14 +177,22 @@ prompt_set(EditLine *el, el_pfunc_t prf, int op)
* Retrieve the prompt printing function
*/
protected int
-prompt_get(EditLine *el, el_pfunc_t *prf, int op)
+prompt_get(EditLine *el, el_pfunc_t *prf, Char *c, int op)
{
+ el_prompt_t *p;
if (prf == NULL)
- return (-1);
+ return -1;
+
if (op == EL_PROMPT)
- *prf = el->el_prompt.p_func;
+ p = &el->el_prompt;
else
- *prf = el->el_rprompt.p_func;
- return (0);
+ p = &el->el_rprompt;
+
+ if (prf)
+ *prf = p->p_func;
+ if (c)
+ *c = p->p_ignore;
+
+ return 0;
}
diff --git a/cmd-line-utils/libedit/prompt.h b/cmd-line-utils/libedit/prompt.h
index d18110861f8..af63b82b684 100644
--- a/cmd-line-utils/libedit/prompt.h
+++ b/cmd-line-utils/libedit/prompt.h
@@ -1,4 +1,4 @@
-/* $NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $ */
+/* $NetBSD: prompt.h,v 1.10 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -42,16 +42,18 @@
#include "histedit.h"
-typedef char * (*el_pfunc_t)(EditLine*);
+typedef Char *(*el_pfunc_t)(EditLine *);
typedef struct el_prompt_t {
- el_pfunc_t p_func; /* Function to return the prompt */
- coord_t p_pos; /* position in the line after prompt */
+ el_pfunc_t p_func; /* Function to return the prompt */
+ coord_t p_pos; /* position in the line after prompt */
+ Char p_ignore; /* character to start/end literal */
+ int p_wide;
} el_prompt_t;
protected void prompt_print(EditLine *, int);
-protected int prompt_set(EditLine *, el_pfunc_t, int);
-protected int prompt_get(EditLine *, el_pfunc_t *, int);
+protected int prompt_set(EditLine *, el_pfunc_t, Char, int, int);
+protected int prompt_get(EditLine *, el_pfunc_t *, Char *, int);
protected int prompt_init(EditLine *);
protected void prompt_end(EditLine *);
diff --git a/cmd-line-utils/libedit/read.c b/cmd-line-utils/libedit/read.c
index ac768142e79..a919b888965 100644
--- a/cmd-line-utils/libedit/read.c
+++ b/cmd-line-utils/libedit/read.c
@@ -1,4 +1,4 @@
-/* $NetBSD: read.c,v 1.43 2009/02/05 19:15:44 christos Exp $ */
+/* $NetBSD: read.c,v 1.67 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -48,14 +48,15 @@ static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
+#include <limits.h>
#include "el.h"
-#define OKCMD -1
+#define OKCMD -1 /* must be -1! */
private int read__fixio(int, int);
private int read_preread(EditLine *);
-private int read_char(EditLine *, char *);
-private int read_getcmd(EditLine *, el_action_t *, char *);
+private int read_char(EditLine *, Char *);
+private int read_getcmd(EditLine *, el_action_t *, Char *);
private void read_pop(c_macro_t *);
/* read_init():
@@ -89,7 +90,7 @@ el_read_setfn(EditLine *el, el_rfunc_t rc)
protected el_rfunc_t
el_read_getfn(EditLine *el)
{
- return (el->el_read.read_char == read_char) ?
+ return el->el_read.read_char == read_char ?
EL_BUILTIN_GETCFN : el->el_read.read_char;
}
@@ -131,7 +132,7 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#ifdef EWOULDBLOCK
case EWOULDBLOCK:
#ifndef TRY_AGAIN
-#define TRY_AGAIN
+#define TRY_AGAIN
#endif
#endif /* EWOULDBLOCK */
@@ -139,7 +140,7 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EAGAIN:
#ifndef TRY_AGAIN
-#define TRY_AGAIN
+#define TRY_AGAIN
#endif
#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
#endif /* POSIX && EAGAIN */
@@ -148,10 +149,10 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#ifdef TRY_AGAIN
#if defined(F_SETFL) && defined(O_NDELAY)
if ((e = fcntl(fd, F_GETFL, 0)) == -1)
- return (-1);
+ return -1;
if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
- return (-1);
+ return -1;
else
e = 1;
#endif /* F_SETFL && O_NDELAY */
@@ -160,21 +161,21 @@ read__fixio(int fd __attribute__((__unused__)), int e)
{
int zero = 0;
- if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1)
- return (-1);
+ if (ioctl(fd, FIONBIO, &zero) == -1)
+ return -1;
else
e = 1;
}
#endif /* FIONBIO */
#endif /* TRY_AGAIN */
- return (e ? 0 : -1);
+ return e ? 0 : -1;
case EINTR:
- return (0);
+ return 0;
default:
- return (-1);
+ return -1;
}
}
@@ -188,10 +189,13 @@ read_preread(EditLine *el)
int chrs = 0;
if (el->el_tty.t_mode == ED_IO)
- return (0);
+ return 0;
+#ifndef WIDECHAR
+/* FIONREAD attempts to buffer up multiple bytes, and to make that work
+ * properly with partial wide/UTF-8 characters would need some careful work. */
#ifdef FIONREAD
- (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
+ (void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs > 0) {
char buf[EL_BUFSIZ];
@@ -203,8 +207,8 @@ read_preread(EditLine *el)
}
}
#endif /* FIONREAD */
-
- return (chrs > 0);
+#endif
+ return chrs > 0;
}
@@ -212,33 +216,37 @@ read_preread(EditLine *el)
* Push a macro
*/
public void
-el_push(EditLine *el, const char *str)
+FUN(el,push)(EditLine *el, const Char *str)
{
c_macro_t *ma = &el->el_chared.c_macro;
if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
ma->level++;
- if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
+ if ((ma->macro[ma->level] = Strdup(str)) != NULL)
return;
ma->level--;
}
- term_beep(el);
- term__flush(el);
+ terminal_beep(el);
+ terminal__flush(el);
}
/* read_getcmd():
* Return next command from the input stream.
+ * Character values > 255 are not looked up in the map, but inserted.
*/
private int
-read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
+read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
{
el_action_t cmd;
int num;
+ el->el_errno = 0;
do {
- if ((num = el_getc(el, ch)) != 1) /* if EOF or error */
- return (num);
+ if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
+ el->el_errno = num == 0 ? 0 : errno;
+ return num;
+ }
#ifdef KANJI
if ((*ch & 0200)) {
@@ -252,15 +260,20 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el->el_state.metanext = 0;
*ch |= 0200;
}
- cmd = el->el_map.current[(unsigned char) *ch];
+#ifdef WIDECHAR
+ if (*ch >= N_KEYS)
+ cmd = ED_INSERT;
+ else
+#endif
+ cmd = el->el_map.current[(unsigned char) *ch];
if (cmd == ED_SEQUENCE_LEAD_IN) {
- key_value_t val;
- switch (key_get(el, ch, &val)) {
+ keymacro_value_t val;
+ switch (keymacro_get(el, ch, &val)) {
case XK_CMD:
cmd = val.cmd;
break;
case XK_STR:
- el_push(el, val.str);
+ FUN(el,push)(el, val.str);
break;
#ifdef notyet
case XK_EXE:
@@ -277,28 +290,82 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el->el_map.current = el->el_map.key;
} while (cmd == ED_SEQUENCE_LEAD_IN);
*cmdnum = cmd;
- return (OKCMD);
+ return OKCMD;
}
-
/* read_char():
* Read a character from the tty.
*/
private int
-read_char(EditLine *el, char *cp)
+read_char(EditLine *el, Char *cp)
{
- int num_read;
+ ssize_t num_read;
int tried = 0;
+ char cbuf[MB_LEN_MAX];
+ size_t cbp = 0;
+ int bytes = 0;
- while ((num_read = read(el->el_infd, cp, 1)) == -1)
+#ifdef WIDECHAR
+static mbstate_t state, temp_state;
+memset(&state, 0, sizeof(mbstate_t));
+#endif
+
+ again:
+ el->el_signal->sig_no = 0;
+ while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
+ switch (el->el_signal->sig_no) {
+ case SIGCONT:
+ FUN(el,set)(el, EL_REFRESH);
+ /*FALLTHROUGH*/
+ case SIGWINCH:
+ sig_set(el);
+ goto again;
+ default:
+ break;
+ }
if (!tried && read__fixio(el->el_infd, errno) == 0)
tried = 1;
else {
*cp = '\0';
- return (-1);
+ return -1;
}
+ }
+
+#ifdef WIDECHAR
+ ++cbp;
+ if (cbp > (size_t) MB_CUR_MAX) { /* "shouldn't happen" */
+ *cp = '\0';
+ return (-1);
+ }
+
+ temp_state= state;
+
+ if ((bytes = mbrtowc(cp, cbuf, cbp, &state)) == -2)
+ {
+ /* Incomplete sequence, restore the state and scan more bytes. */
+ state= temp_state;
+ goto again;
+ }
+ else if (bytes == -1)
+ {
+ /* Invalid sequence, reset the state and continue. */
+ cbp= 0;
+ memset(&state, 0, sizeof(mbstate_t));
+ goto again;
+ }
+ /* We successfully read one single or multi-byte character */
+#else
+ *cp = (unsigned char)cbuf[0];
+#endif
- return (num_read);
+#if 0
+ if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) {
+ cbp = 0; /* skip this character */
+ goto again;
+ }
+#endif
+
+ return (int)num_read;
}
/* read_pop():
@@ -310,8 +377,9 @@ read_pop(c_macro_t *ma)
int i;
el_free(ma->macro[0]);
- for (i = ma->level--; i > 0; i--)
- ma->macro[i - 1] = ma->macro[i];
+ for (i = 0; i < ma->level; i++)
+ ma->macro[i] = ma->macro[i + 1];
+ ma->level--;
ma->offset = 0;
}
@@ -319,12 +387,12 @@ read_pop(c_macro_t *ma)
* Read a character
*/
public int
-el_getc(EditLine *el, char *cp)
+FUN(el,getc)(EditLine *el, Char *cp)
{
int num_read;
c_macro_t *ma = &el->el_chared.c_macro;
- term__flush(el);
+ terminal__flush(el);
for (;;) {
if (ma->level < 0) {
if (!read_preread(el))
@@ -339,30 +407,34 @@ el_getc(EditLine *el, char *cp)
continue;
}
- *cp = ma->macro[0][ma->offset++] & 0377;
+ *cp = ma->macro[0][ma->offset++];
if (ma->macro[0][ma->offset] == '\0') {
/* Needed for QuoteMode On */
read_pop(ma);
}
- return (1);
+ return 1;
}
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Turning raw mode on\n");
#endif /* DEBUG_READ */
if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
- return (0);
+ return 0;
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Reading a character\n");
#endif /* DEBUG_READ */
num_read = (*el->el_read.read_char)(el, cp);
+#ifdef WIDECHAR
+ if (el->el_flags & NARROW_READ)
+ *cp = *(char *)(void *)cp;
+#endif
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
#endif /* DEBUG_READ */
- return (num_read);
+ return num_read;
}
protected void
@@ -383,7 +455,7 @@ read_prepare(EditLine *el)
re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED)
- term__flush(el);
+ terminal__flush(el);
}
protected void
@@ -395,27 +467,32 @@ read_finish(EditLine *el)
sig_clr(el);
}
-public const char *
-el_gets(EditLine *el, int *nread)
+public const Char *
+FUN(el,gets)(EditLine *el, int *nread)
{
int retval;
el_action_t cmdnum = 0;
int num; /* how many chars we have read at NL */
- char ch;
+ Char ch, *cp;
int crlf = 0;
+ int nrb;
#ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */
+ if (nread == NULL)
+ nread = &nrb;
+ *nread = 0;
+
if (el->el_flags & NO_TTY) {
- char *cp = el->el_line.buffer;
size_t idx;
- while ((*el->el_read.read_char)(el, cp) == 1) {
+ cp = el->el_line.buffer;
+ while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space for next character */
if (cp + 1 >= el->el_line.limit) {
- idx = (cp - el->el_line.buffer);
- if (!ch_enlargebufs(el, 2))
+ idx = (size_t)(cp - el->el_line.buffer);
+ if (!ch_enlargebufs(el, (size_t)2))
break;
cp = &el->el_line.buffer[idx];
}
@@ -425,12 +502,13 @@ el_gets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
+ if (num == -1) {
+ if (errno == EINTR)
+ cp = el->el_line.buffer;
+ el->el_errno = errno;
+ }
- el->el_line.cursor = el->el_line.lastchar = cp;
- *cp = '\0';
- if (nread)
- *nread = el->el_line.cursor - el->el_line.buffer;
- return (el->el_line.buffer);
+ goto noedit;
}
@@ -438,12 +516,12 @@ el_gets(EditLine *el, int *nread)
if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
long chrs = 0;
- (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
+ (void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs == 0) {
if (tty_rawmode(el) < 0) {
- if (nread)
- *nread = 0;
- return (NULL);
+ errno = 0;
+ *nread = 0;
+ return NULL;
}
}
}
@@ -453,25 +531,23 @@ el_gets(EditLine *el, int *nread)
read_prepare(el);
if (el->el_flags & EDIT_DISABLED) {
- char *cp;
size_t idx;
+
if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer;
else
cp = el->el_line.lastchar;
- term__flush(el);
+ terminal__flush(el);
- while ((*el->el_read.read_char)(el, cp) == 1) {
+ while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space next character */
if (cp + 1 >= el->el_line.limit) {
- idx = (cp - el->el_line.buffer);
- if (!ch_enlargebufs(el, 2))
+ idx = (size_t)(cp - el->el_line.buffer);
+ if (!ch_enlargebufs(el, (size_t)2))
break;
cp = &el->el_line.buffer[idx];
}
- if (*cp == 4) /* ought to be stty eof */
- break;
cp++;
crlf = cp[-1] == '\r' || cp[-1] == '\n';
if (el->el_flags & UNBUFFERED)
@@ -480,11 +556,13 @@ el_gets(EditLine *el, int *nread)
break;
}
- el->el_line.cursor = el->el_line.lastchar = cp;
- *cp = '\0';
- if (nread)
- *nread = el->el_line.cursor - el->el_line.buffer;
- return (el->el_line.buffer);
+ if (num == -1) {
+ if (errno == EINTR)
+ cp = el->el_line.buffer;
+ el->el_errno = errno;
+ }
+
+ goto noedit;
}
for (num = OKCMD; num == OKCMD;) { /* while still editing this
@@ -500,6 +578,12 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */
break;
}
+ if (el->el_errno == EINTR) {
+ el->el_line.buffer[0] = '\0';
+ el->el_line.lastchar =
+ el->el_line.cursor = el->el_line.buffer;
+ break;
+ }
if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
@@ -530,7 +614,7 @@ el_gets(EditLine *el, int *nread)
el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
if (cmdnum == VI_DELETE_PREV_CHAR &&
el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
- && el_isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
+ && Isprint(el->el_chared.c_redo.pos[-1]))
el->el_chared.c_redo.pos--;
else
*el->el_chared.c_redo.pos++ = ch;
@@ -561,7 +645,7 @@ el_gets(EditLine *el, int *nread)
case CC_REFRESH_BEEP:
re_refresh(el);
- term_beep(el);
+ terminal_beep(el);
break;
case CC_NORM: /* normal char */
@@ -582,7 +666,7 @@ el_gets(EditLine *el, int *nread)
break;
case CC_NEWLINE: /* normal end of line */
- num = el->el_line.lastchar - el->el_line.buffer;
+ num = (int)(el->el_line.lastchar - el->el_line.buffer);
break;
case CC_FATAL: /* fatal error, reset to known state */
@@ -593,7 +677,7 @@ el_gets(EditLine *el, int *nread)
/* put (real) cursor in a known place */
re_clear_display(el); /* reset the display stuff */
ch_reset(el, 1); /* reset the input pointers */
- re_refresh(el); /* print the prompt again */
+ re_refresh(el); /* print the prompt again */
break;
case CC_ERROR:
@@ -602,8 +686,8 @@ el_gets(EditLine *el, int *nread)
(void) fprintf(el->el_errfile,
"*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */
- term_beep(el);
- term__flush(el);
+ terminal_beep(el);
+ terminal__flush(el);
break;
}
el->el_state.argument = 1;
@@ -613,15 +697,26 @@ el_gets(EditLine *el, int *nread)
break;
}
- term__flush(el); /* flush any buffered output */
+ terminal__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el);
- if (nread)
- *nread = num;
+ *nread = num != -1 ? num : 0;
} else {
- if (nread)
- *nread = el->el_line.lastchar - el->el_line.buffer;
+ *nread = (int)(el->el_line.lastchar - el->el_line.buffer);
}
- return (num ? el->el_line.buffer : NULL);
+ goto done;
+noedit:
+ el->el_line.cursor = el->el_line.lastchar = cp;
+ *cp = '\0';
+ *nread = (int)(el->el_line.cursor - el->el_line.buffer);
+done:
+ if (*nread == 0) {
+ if (num == -1) {
+ *nread = -1;
+ errno = el->el_errno;
+ }
+ return NULL;
+ } else
+ return el->el_line.buffer;
}
diff --git a/cmd-line-utils/libedit/read.h b/cmd-line-utils/libedit/read.h
index bd8d4c1f5bb..852606a9c17 100644
--- a/cmd-line-utils/libedit/read.h
+++ b/cmd-line-utils/libedit/read.h
@@ -1,4 +1,4 @@
-/* $NetBSD: read.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */
+/* $NetBSD: read.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
#ifndef _h_el_read
#define _h_el_read
-typedef int (*el_rfunc_t)(EditLine *, char *);
+typedef int (*el_rfunc_t)(EditLine *, Char *);
typedef struct el_read_t {
el_rfunc_t read_char; /* Function to read a character */
diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c
index 0318ab409b3..eaf26d4c497 100644
--- a/cmd-line-utils/libedit/readline.c
+++ b/cmd-line-utils/libedit/readline.c
@@ -1,4 +1,4 @@
-/* $NetBSD: readline.c,v 1.78 2009/02/05 19:15:26 christos Exp $ */
+/* $NetBSD: readline.c,v 1.99 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -69,6 +69,7 @@ void rl_deprep_terminal(void);
/* readline compatibility stuff - look at readline sources/documentation */
/* to see what these variables mean */
const char *rl_library_version = "EditLine wrapper";
+int rl_readline_version = RL_READLINE_VERSION;
static char empty[] = { '\0' };
static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' };
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
@@ -117,6 +118,7 @@ Function *rl_startup_hook = NULL;
VFunction *rl_completion_display_matches_hook = NULL;
VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
+KEYMAP_ENTRY_ARRAY emacs_meta_keymap;
/*
* The current prompt string.
@@ -174,7 +176,7 @@ static char *
_get_prompt(EditLine *el __attribute__((__unused__)))
{
rl_already_prompted = 1;
- return (rl_prompt);
+ return rl_prompt;
}
@@ -188,12 +190,12 @@ _move_history(int op)
static HIST_ENTRY rl_he;
if (history(h, &ev, op) != 0)
- return (HIST_ENTRY *) NULL;
+ return NULL;
rl_he.line = ev.str;
rl_he.data = NULL;
- return (&rl_he);
+ return &rl_he;
}
@@ -209,10 +211,34 @@ _getc_function(EditLine *el __attribute__((__unused__)), char *c)
i = (*rl_getc_function)(NULL);
if (i == -1)
return 0;
- *c = i;
+ *c = (char)i;
return 1;
}
+static void
+_resize_fun(EditLine *el, void *a)
+{
+ const LineInfo *li;
+ char **ap = a;
+
+ li = el_line(el);
+ /* a cheesy way to get rid of const cast. */
+ *ap = memchr(li->buffer, *li->buffer, (size_t)1);
+}
+
+static const char *
+_default_history_file(void)
+{
+ struct passwd *p;
+ static char path[PATH_MAX];
+
+ if (*path)
+ return path;
+ if ((p = getpwuid(getuid())) == NULL)
+ return NULL;
+ (void)snprintf(path, sizeof(path), "%s/.history", p->pw_dir);
+ return path;
+}
/*
* READLINE compatibility stuff
@@ -224,14 +250,22 @@ _getc_function(EditLine *el __attribute__((__unused__)), char *c)
int
rl_set_prompt(const char *prompt)
{
+ char *p;
+
if (!prompt)
prompt = "";
if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0)
return 0;
if (rl_prompt)
- free(rl_prompt);
+ el_free(rl_prompt);
rl_prompt = strdup(prompt);
- return rl_prompt == NULL ? -1 : 0;
+ if (rl_prompt == NULL)
+ return -1;
+
+ while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL)
+ *p = RL_PROMPT_START_IGNORE;
+
+ return 0;
}
/*
@@ -241,7 +275,6 @@ int
rl_initialize(void)
{
HistEvent ev;
- const LineInfo *li;
int editmode = 1;
struct termios t;
@@ -268,13 +301,16 @@ rl_initialize(void)
h = history_init();
if (!e || !h)
- return (-1);
+ return -1;
history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */
history_length = 0;
max_input_history = INT_MAX;
el_set(e, EL_HIST, history, h);
+ /* Setup resize function */
+ el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer);
+
/* setup getc function if valid */
if (rl_getc_function)
el_set(e, EL_GETCFN, _getc_function);
@@ -285,7 +321,7 @@ rl_initialize(void)
el_end(e);
return -1;
}
- el_set(e, EL_PROMPT, _get_prompt);
+ el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE);
el_set(e, EL_SIGNAL, rl_catch_signals);
/* set default mode to "emacs"-style and read setting afterwards */
@@ -312,7 +348,38 @@ rl_initialize(void)
"ReadLine compatible suspend function",
_el_rl_tstp);
el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
-
+
+ /*
+ * Set some readline compatible key-bindings.
+ */
+ el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL);
+
+ /*
+ * Allow the use of Home/End keys.
+ */
+ el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL);
+ el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL);
+ el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL);
+ el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL);
+ el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL);
+ el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL);
+
+ /*
+ * Allow the use of the Delete/Insert keys.
+ */
+ el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL);
+ el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL);
+
+ /*
+ * Ctrl-left-arrow and Ctrl-right-arrow for word moving.
+ */
+ el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL);
+ el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);
+ el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL);
+ el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL);
+ el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL);
+ el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);
+
/* read settings from configuration file */
el_source(e, NULL);
@@ -320,15 +387,13 @@ rl_initialize(void)
* Unfortunately, some applications really do use rl_point
* and rl_line_buffer directly.
*/
- li = el_line(e);
- /* a cheesy way to get rid of const cast. */
- rl_line_buffer = memchr(li->buffer, *li->buffer, 1);
+ _resize_fun(e, &rl_line_buffer);
_rl_update_pos();
if (rl_startup_hook)
(*rl_startup_hook)(NULL, 0);
- return (0);
+ return 0;
}
@@ -437,7 +502,7 @@ _rl_compat_sub(const char *str, const char *what, const char *with,
} else
s++;
}
- r = result = malloc(len + 1);
+ r = result = el_malloc((len + 1) * sizeof(*r));
if (result == NULL)
return NULL;
s = str;
@@ -448,13 +513,13 @@ _rl_compat_sub(const char *str, const char *what, const char *with,
s += what_len;
if (!globally) {
(void)strcpy(r, s);
- return(result);
+ return result;
}
} else
*r++ = *s++;
}
*r = '\0';
- return(result);
+ return result;
}
static char *last_search_pat; /* last !?pat[?] search pattern */
@@ -471,14 +536,14 @@ get_history_event(const char *cmd, int *cindex, int qchar)
idx = *cindex;
if (cmd[idx++] != history_expansion_char)
- return(NULL);
+ return NULL;
/* find out which event to take */
if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') {
if (history(h, &ev, H_FIRST) != 0)
- return(NULL);
+ return NULL;
*cindex = cmd[idx]? (idx + 1):idx;
- return(ev.str);
+ return ev.str;
}
sign = 0;
if (cmd[idx] == '-') {
@@ -498,10 +563,10 @@ get_history_event(const char *cmd, int *cindex, int qchar)
num = history_length - num + 1;
if (!(rl_he = history_get(num)))
- return(NULL);
+ return NULL;
*cindex = idx;
- return(rl_he->line);
+ return rl_he->line;
}
sub = 0;
if (cmd[idx] == '?') {
@@ -519,15 +584,15 @@ get_history_event(const char *cmd, int *cindex, int qchar)
break;
idx++;
}
- len = idx - begin;
+ len = (size_t)idx - (size_t)begin;
if (sub && cmd[idx] == '?')
idx++;
if (sub && len == 0 && last_search_pat && *last_search_pat)
pat = last_search_pat;
else if (len == 0)
- return(NULL);
+ return NULL;
else {
- if ((pat = malloc(len + 1)) == NULL)
+ if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL)
return NULL;
(void)strncpy(pat, cmd + begin, len);
pat[len] = '\0';
@@ -535,15 +600,15 @@ get_history_event(const char *cmd, int *cindex, int qchar)
if (history(h, &ev, H_CURR) != 0) {
if (pat != last_search_pat)
- free(pat);
- return (NULL);
+ el_free(pat);
+ return NULL;
}
num = ev.num;
if (sub) {
if (pat != last_search_pat) {
if (last_search_pat)
- free(last_search_pat);
+ el_free(last_search_pat);
last_search_pat = pat;
}
ret = history_search(pat, -1);
@@ -555,21 +620,21 @@ get_history_event(const char *cmd, int *cindex, int qchar)
history(h, &ev, H_FIRST);
(void)fprintf(rl_outstream, "%s: Event not found\n", pat);
if (pat != last_search_pat)
- free(pat);
- return(NULL);
+ el_free(pat);
+ return NULL;
}
if (sub && len) {
if (last_search_match && last_search_match != pat)
- free(last_search_match);
+ el_free(last_search_match);
last_search_match = pat;
}
if (pat != last_search_pat)
- free(pat);
+ el_free(pat);
if (history(h, &ev, H_CURR) != 0)
- return(NULL);
+ return NULL;
*cindex = idx;
rptr = ev.str;
@@ -621,7 +686,8 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
} else {
if (command[offs + 1] == '#') {
/* use command so far */
- if ((aptr = malloc(offs + 1)) == NULL)
+ if ((aptr = el_malloc((offs + 1) * sizeof(*aptr)))
+ == NULL)
return -1;
(void)strncpy(aptr, command, offs);
aptr[offs] = '\0';
@@ -632,17 +698,19 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
ptr = get_history_event(command + offs, &idx, qchar);
}
- has_mods = command[offs + idx] == ':';
+ has_mods = command[offs + (size_t)idx] == ':';
}
if (ptr == NULL && aptr == NULL)
- return(-1);
+ return -1;
if (!has_mods) {
- *result = strdup(aptr? aptr : ptr);
+ *result = strdup(aptr ? aptr : ptr);
if (aptr)
- free(aptr);
- return(1);
+ el_free(aptr);
+ if (*result == NULL)
+ return -1;
+ return 1;
}
cmd = command + offs + idx + 1;
@@ -687,18 +755,18 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
(void)fprintf(rl_outstream, "%s: Bad word specifier",
command + offs + idx);
if (aptr)
- free(aptr);
- return(-1);
+ el_free(aptr);
+ return -1;
}
} else
tmp = strdup(aptr? aptr:ptr);
if (aptr)
- free(aptr);
+ el_free(aptr);
if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) {
*result = tmp;
- return(1);
+ return 1;
}
for (; *cmd; cmd++) {
@@ -710,7 +778,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
} else if (*cmd == 't') { /* remove leading path */
if ((aptr = strrchr(tmp, '/')) != NULL) {
aptr = strdup(aptr + 1);
- free(tmp);
+ el_free(tmp);
tmp = aptr;
}
} else if (*cmd == 'r') { /* remove trailing suffix */
@@ -719,7 +787,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
} else if (*cmd == 'e') { /* remove all but suffix */
if ((aptr = strrchr(tmp, '.')) != NULL) {
aptr = strdup(aptr);
- free(tmp);
+ el_free(tmp);
tmp = aptr;
}
} else if (*cmd == 'p') /* print only */
@@ -736,10 +804,10 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
else if (*cmd == 's') {
delim = *(++cmd), cmd++;
size = 16;
- what = realloc(from, size);
+ what = el_realloc(from, size * sizeof(*what));
if (what == NULL) {
- free(from);
- free(tmp);
+ el_free(from);
+ el_free(tmp);
return 0;
}
len = 0;
@@ -748,11 +816,12 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
cmd++;
if (len >= size) {
char *nwhat;
- nwhat = realloc(what,
- (size <<= 1));
+ nwhat = el_realloc(what,
+ (size <<= 1) *
+ sizeof(*nwhat));
if (nwhat == NULL) {
- free(what);
- free(tmp);
+ el_free(what);
+ el_free(tmp);
return 0;
}
what = nwhat;
@@ -762,17 +831,17 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
what[len] = '\0';
from = what;
if (*what == '\0') {
- free(what);
+ el_free(what);
if (search) {
from = strdup(search);
if (from == NULL) {
- free(tmp);
+ el_free(tmp);
return 0;
}
} else {
from = NULL;
- free(tmp);
- return (-1);
+ el_free(tmp);
+ return -1;
}
}
cmd++; /* shift after delim */
@@ -780,10 +849,10 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
continue;
size = 16;
- with = realloc(to, size);
+ with = el_realloc(to, size * sizeof(*with));
if (with == NULL) {
- free(to);
- free(tmp);
+ el_free(to);
+ el_free(tmp);
return -1;
}
len = 0;
@@ -792,10 +861,11 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
if (len + from_len + 1 >= size) {
char *nwith;
size += from_len + 1;
- nwith = realloc(with, size);
+ nwith = el_realloc(with,
+ size * sizeof(*nwith));
if (nwith == NULL) {
- free(with);
- free(tmp);
+ el_free(with);
+ el_free(tmp);
return -1;
}
with = nwith;
@@ -818,14 +888,14 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen,
aptr = _rl_compat_sub(tmp, from, to, g_on);
if (aptr) {
- free(tmp);
+ el_free(tmp);
tmp = aptr;
}
g_on = 0;
}
}
*result = tmp;
- return (p_on? 2:1);
+ return p_on? 2:1;
}
@@ -844,13 +914,13 @@ history_expand(char *str, char **output)
if (history_expansion_char == 0) {
*output = strdup(str);
- return(0);
+ return 0;
}
*output = NULL;
if (str[0] == history_subst_char) {
/* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
- *output = malloc(strlen(str) + 4 + 1);
+ *output = el_malloc((strlen(str) + 4 + 1) * sizeof(*output));
if (*output == NULL)
return 0;
(*output)[0] = (*output)[1] = history_expansion_char;
@@ -867,11 +937,12 @@ history_expand(char *str, char **output)
#define ADD_STRING(what, len, fr) \
{ \
if (idx + len + 1 > size) { \
- char *nresult = realloc(result, (size += len + 1));\
+ char *nresult = el_realloc(result, \
+ (size += len + 1) * sizeof(*nresult)); \
if (nresult == NULL) { \
- free(*output); \
+ el_free(*output); \
if (/*CONSTCOND*/fr) \
- free(tmp); \
+ el_free(tmp); \
return 0; \
} \
result = nresult; \
@@ -938,7 +1009,7 @@ loop:
ADD_STRING(tmp, len, 1);
}
if (tmp) {
- free(tmp);
+ el_free(tmp);
tmp = NULL;
}
i = j;
@@ -955,10 +1026,10 @@ loop:
ret = -1;
#endif
}
- free(*output);
+ el_free(*output);
*output = result;
- return (ret);
+ return ret;
}
/*
@@ -968,40 +1039,39 @@ char *
history_arg_extract(int start, int end, const char *str)
{
size_t i, len, max;
- char **arr, *result;
+ char **arr, *result = NULL;
arr = history_tokenize(str);
if (!arr)
- return(NULL);
- if (arr && *arr == NULL) {
- free(arr);
- return(NULL);
- }
+ return NULL;
+ if (arr && *arr == NULL)
+ goto out;
for (max = 0; arr[max]; max++)
continue;
max--;
if (start == '$')
- start = max;
+ start = (int)max;
if (end == '$')
- end = max;
+ end = (int)max;
if (end < 0)
- end = max + end + 1;
+ end = (int)max + end + 1;
if (start < 0)
start = end;
- if (start < 0 || end < 0 || (size_t)start > max || (size_t)end > max || start > end)
- return(NULL);
+ if (start < 0 || end < 0 || (size_t)start > max ||
+ (size_t)end > max || start > end)
+ goto out;
- for (i = start, len = 0; i <= (size_t)end; i++)
+ for (i = (size_t)start, len = 0; i <= (size_t)end; i++)
len += strlen(arr[i]) + 1;
len++;
- result = malloc(len);
+ result = el_malloc(len * sizeof(*result));
if (result == NULL)
- return NULL;
+ goto out;
- for (i = start, len = 0; i <= (size_t)end; i++) {
+ for (i = (size_t)start, len = 0; i <= (size_t)end; i++) {
(void)strcpy(result + len, arr[i]);
len += strlen(arr[i]);
if (i < (size_t)end)
@@ -1009,11 +1079,12 @@ history_arg_extract(int start, int end, const char *str)
}
result[len] = '\0';
+out:
for (i = 0; arr[i]; i++)
- free(arr[i]);
- free(arr);
+ el_free(arr[i]);
+ el_free(arr);
- return(result);
+ return result;
}
/*
@@ -1050,19 +1121,19 @@ history_tokenize(const char *str)
if (idx + 2 >= size) {
char **nresult;
size <<= 1;
- nresult = realloc(result, size * sizeof(char *));
+ nresult = el_realloc(result, (size_t)size * sizeof(*nresult));
if (nresult == NULL) {
- free(result);
+ el_free(result);
return NULL;
}
result = nresult;
}
- len = i - start;
- temp = malloc(len + 1);
+ len = (size_t)i - (size_t)start;
+ temp = el_malloc((size_t)(len + 1) * sizeof(*temp));
if (temp == NULL) {
for (i = 0; i < idx; i++)
- free(result[i]);
- free(result);
+ el_free(result[i]);
+ el_free(result);
return NULL;
}
(void)strncpy(temp, &str[start], len);
@@ -1072,7 +1143,7 @@ history_tokenize(const char *str)
if (str[i])
i++;
}
- return (result);
+ return result;
}
@@ -1104,7 +1175,7 @@ unstifle_history(void)
history(h, &ev, H_SETSIZE, INT_MAX);
omax = max_input_history;
max_input_history = INT_MAX;
- return (omax); /* some value _must_ be returned */
+ return omax; /* some value _must_ be returned */
}
@@ -1113,7 +1184,146 @@ history_is_stifled(void)
{
/* cannot return true answer */
- return (max_input_history != INT_MAX);
+ return max_input_history != INT_MAX;
+}
+
+static const char _history_tmp_template[] = "/tmp/.historyXXXXXX";
+
+int
+history_truncate_file (const char *filename, int nlines)
+{
+ int ret = 0;
+ FILE *fp, *tp;
+ char template[sizeof(_history_tmp_template)];
+ char buf[4096];
+ int fd;
+ char *cp;
+ off_t off;
+ int count = 0;
+ ssize_t left = 0;
+
+ if (filename == NULL && (filename = _default_history_file()) == NULL)
+ return errno;
+ if ((fp = fopen(filename, "r+")) == NULL)
+ return errno;
+ strcpy(template, _history_tmp_template);
+ if ((fd = mkstemp(template)) == -1) {
+ ret = errno;
+ goto out1;
+ }
+
+ if ((tp = fdopen(fd, "r+")) == NULL) {
+ close(fd);
+ ret = errno;
+ goto out2;
+ }
+
+ for(;;) {
+ if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) {
+ if (ferror(fp)) {
+ ret = errno;
+ break;
+ }
+ if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) ==
+ (off_t)-1) {
+ ret = errno;
+ break;
+ }
+ left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp);
+ if (ferror(fp)) {
+ ret = errno;
+ break;
+ }
+ if (left == 0) {
+ count--;
+ left = sizeof(buf);
+ } else if (fwrite(buf, (size_t)left, (size_t)1, tp)
+ != 1) {
+ ret = errno;
+ break;
+ }
+ fflush(tp);
+ break;
+ }
+ if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) {
+ ret = errno;
+ break;
+ }
+ count++;
+ }
+ if (ret)
+ goto out3;
+ cp = buf + left - 1;
+ if(*cp != '\n')
+ cp++;
+ for(;;) {
+ while (--cp >= buf) {
+ if (*cp == '\n') {
+ if (--nlines == 0) {
+ if (++cp >= buf + sizeof(buf)) {
+ count++;
+ cp = buf;
+ }
+ break;
+ }
+ }
+ }
+ if (nlines <= 0 || count == 0)
+ break;
+ count--;
+ if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) {
+ ret = errno;
+ break;
+ }
+ if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) {
+ if (ferror(tp)) {
+ ret = errno;
+ break;
+ }
+ ret = EAGAIN;
+ break;
+ }
+ cp = buf + sizeof(buf);
+ }
+
+ if (ret || nlines > 0)
+ goto out3;
+
+ if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) {
+ ret = errno;
+ goto out3;
+ }
+
+ if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) ==
+ (off_t)-1) {
+ ret = errno;
+ goto out3;
+ }
+
+ for(;;) {
+ if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) {
+ if (ferror(fp))
+ ret = errno;
+ break;
+ }
+ if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) {
+ ret = errno;
+ break;
+ }
+ }
+ fflush(fp);
+ if((off = ftello(fp)) > 0) {
+ if (ftruncate(fileno(fp), off) == -1)
+ ret = errno;
+ }
+out3:
+ fclose(tp);
+out2:
+ unlink(template);
+out1:
+ fclose(fp);
+
+ return ret;
}
@@ -1127,7 +1337,10 @@ read_history(const char *filename)
if (h == NULL || e == NULL)
rl_initialize();
- return (history(h, &ev, H_LOAD, filename) == -1);
+ if (filename == NULL && (filename = _default_history_file()) == NULL)
+ return errno;
+ return history(h, &ev, H_LOAD, filename) == -1 ?
+ (errno ? errno : EINVAL) : 0;
}
@@ -1141,7 +1354,10 @@ write_history(const char *filename)
if (h == NULL || e == NULL)
rl_initialize();
- return (history(h, &ev, H_SAVE, filename) == -1);
+ if (filename == NULL && (filename = _default_history_file()) == NULL)
+ return errno;
+ return history(h, &ev, H_SAVE, filename) == -1 ?
+ (errno ? errno : EINVAL) : 0;
}
@@ -1162,24 +1378,23 @@ history_get(int num)
/* save current position */
if (history(h, &ev, H_CURR) != 0)
- return (NULL);
+ return NULL;
curr_num = ev.num;
- /* start from most recent */
- if (history(h, &ev, H_FIRST) != 0)
- return (NULL); /* error */
+ /* start from the oldest */
+ if (history(h, &ev, H_LAST) != 0)
+ return NULL; /* error */
- /* look backwards for event matching specified offset */
- if (history(h, &ev, H_NEXT_EVENT, num + 1))
- return (NULL);
+ /* look forwards for event matching specified offset */
+ if (history(h, &ev, H_NEXT_EVDATA, num, &she.data))
+ return NULL;
she.line = ev.str;
- she.data = NULL;
/* restore pointer to where it was */
(void)history(h, &ev, H_SET, curr_num);
- return (&she);
+ return &she;
}
@@ -1198,7 +1413,7 @@ add_history(const char *line)
if (history(h, &ev, H_GETSIZE) == 0)
history_length = ev.num;
- return (!(history_length > 0)); /* return 0 if all is okay */
+ return !(history_length > 0); /* return 0 if all is okay */
}
@@ -1208,26 +1423,75 @@ add_history(const char *line)
HIST_ENTRY *
remove_history(int num)
{
- HIST_ENTRY *she;
+ HIST_ENTRY *he;
HistEvent ev;
if (h == NULL || e == NULL)
rl_initialize();
- if (history(h, &ev, H_DEL, num) != 0)
+ if ((he = el_malloc(sizeof(*he))) == NULL)
return NULL;
- if ((she = malloc(sizeof(*she))) == NULL)
+ if (history(h, &ev, H_DELDATA, num, &he->data) != 0) {
+ el_free(he);
return NULL;
+ }
- she->line = ev.str;
- she->data = NULL;
+ he->line = ev.str;
+ if (history(h, &ev, H_GETSIZE) == 0)
+ history_length = ev.num;
- return she;
+ return he;
}
/*
+ * replace the line and data of the num-th entry
+ */
+HIST_ENTRY *
+replace_history_entry(int num, const char *line, histdata_t data)
+{
+ HIST_ENTRY *he;
+ HistEvent ev;
+ int curr_num;
+
+ if (h == NULL || e == NULL)
+ rl_initialize();
+
+ /* save current position */
+ if (history(h, &ev, H_CURR) != 0)
+ return NULL;
+ curr_num = ev.num;
+
+ /* start from the oldest */
+ if (history(h, &ev, H_LAST) != 0)
+ return NULL; /* error */
+
+ if ((he = el_malloc(sizeof(*he))) == NULL)
+ return NULL;
+
+ /* look forwards for event matching specified offset */
+ if (history(h, &ev, H_NEXT_EVDATA, num, &he->data))
+ goto out;
+
+ he->line = strdup(ev.str);
+ if (he->line == NULL)
+ goto out;
+
+ if (history(h, &ev, H_REPLACE, line, data))
+ goto out;
+
+ /* restore pointer to where it was */
+ if (history(h, &ev, H_SET, curr_num))
+ goto out;
+
+ return he;
+out:
+ el_free(he);
+ return NULL;
+}
+
+/*
* clear the history list - delete all entries
*/
void
@@ -1235,7 +1499,8 @@ clear_history(void)
{
HistEvent ev;
- history(h, &ev, H_CLEAR);
+ (void)history(h, &ev, H_CLEAR);
+ history_length = 0;
}
@@ -1249,15 +1514,15 @@ where_history(void)
int curr_num, off;
if (history(h, &ev, H_CURR) != 0)
- return (0);
+ return 0;
curr_num = ev.num;
- history(h, &ev, H_FIRST);
+ (void)history(h, &ev, H_FIRST);
off = 1;
while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)
off++;
- return (off);
+ return off;
}
@@ -1268,7 +1533,7 @@ HIST_ENTRY *
current_history(void)
{
- return (_move_history(H_CURR));
+ return _move_history(H_CURR);
}
@@ -1279,22 +1544,23 @@ int
history_total_bytes(void)
{
HistEvent ev;
- int curr_num, size;
+ int curr_num;
+ size_t size;
if (history(h, &ev, H_CURR) != 0)
- return (-1);
+ return -1;
curr_num = ev.num;
- history(h, &ev, H_FIRST);
+ (void)history(h, &ev, H_FIRST);
size = 0;
do
- size += strlen(ev.str);
+ size += strlen(ev.str) * sizeof(*ev.str);
while (history(h, &ev, H_NEXT) == 0);
/* get to the same position as before */
history(h, &ev, H_PREV_EVENT, curr_num);
- return (size);
+ return (int)size;
}
@@ -1307,17 +1573,21 @@ history_set_pos(int pos)
HistEvent ev;
int curr_num;
- if (pos > history_length || pos < 0)
- return (-1);
+ if (pos >= history_length || pos < 0)
+ return -1;
- history(h, &ev, H_CURR);
+ (void)history(h, &ev, H_CURR);
curr_num = ev.num;
- if (history(h, &ev, H_SET, pos)) {
- history(h, &ev, H_SET, curr_num);
- return(-1);
+ /*
+ * use H_DELDATA to set to nth history (without delete) by passing
+ * (void **)-1
+ */
+ if (history(h, &ev, H_DELDATA, pos, (void **)-1)) {
+ (void)history(h, &ev, H_SET, curr_num);
+ return -1;
}
- return (0);
+ return 0;
}
@@ -1328,7 +1598,7 @@ HIST_ENTRY *
previous_history(void)
{
- return (_move_history(H_PREV));
+ return _move_history(H_PREV);
}
@@ -1339,7 +1609,7 @@ HIST_ENTRY *
next_history(void)
{
- return (_move_history(H_NEXT));
+ return _move_history(H_NEXT);
}
@@ -1354,17 +1624,17 @@ history_search(const char *str, int direction)
int curr_num;
if (history(h, &ev, H_CURR) != 0)
- return (-1);
+ return -1;
curr_num = ev.num;
for (;;) {
if ((strp = strstr(ev.str, str)) != NULL)
- return (int) (strp - ev.str);
+ return (int)(strp - ev.str);
if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
break;
}
- history(h, &ev, H_SET, curr_num);
- return (-1);
+ (void)history(h, &ev, H_SET, curr_num);
+ return -1;
}
@@ -1376,7 +1646,8 @@ history_search_prefix(const char *str, int direction)
{
HistEvent ev;
- return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str));
+ return (history(h, &ev, direction < 0 ?
+ H_PREV_STR : H_NEXT_STR, str));
}
@@ -1396,24 +1667,24 @@ history_search_pos(const char *str,
pos = (pos > 0) ? 1 : -1;
if (history(h, &ev, H_CURR) != 0)
- return (-1);
+ return -1;
curr_num = ev.num;
if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)
- return (-1);
-
+ return -1;
for (;;) {
if (strstr(ev.str, str))
- return (off);
+ return off;
if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0)
break;
}
/* set "current" pointer back to previous state */
- history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
+ (void)history(h, &ev,
+ pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
- return (-1);
+ return -1;
}
@@ -1436,16 +1707,20 @@ filename_completion_function(const char *name, int state)
* a completion generator for usernames; returns _first_ username
* which starts with supplied text
* text contains a partial username preceded by random character
- * (usually '~'); state is ignored
+ * (usually '~'); state resets search from start (??? should we do that anyway)
* it's callers responsibility to free returned value
*/
char *
username_completion_function(const char *text, int state)
{
- struct passwd *pwd;
+#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
+ struct passwd pwres;
+ char pwbuf[1024];
+#endif
+ struct passwd *pass = NULL;
if (text[0] == '\0')
- return (NULL);
+ return NULL;
if (*text == '~')
text++;
@@ -1453,15 +1728,21 @@ username_completion_function(const char *text, int state)
if (state == 0)
setpwent();
- /* XXXMYSQL: just use non-_r functions for now */
- while ((pwd = getpwent()) && text[0] == pwd->pw_name[0]
- && strcmp(text, pwd->pw_name) == 0);
+ while (
+#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
+ getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pass) == 0 && pass != NULL
+#else
+ (pass = getpwent()) != NULL
+#endif
+ && text[0] == pass->pw_name[0]
+ && strcmp(text, pass->pw_name) == 0)
+ continue;
- if (pwd == NULL) {
+ if (pass == NULL) {
endpwent();
- return (NULL);
+ return NULL;
}
- return (strdup(pwd->pw_name));
+ return strdup(pass->pw_name);
}
@@ -1485,7 +1766,7 @@ void
rl_display_match_list(char **matches, int len, int max)
{
- fn_display_match_list(e, matches, len, max);
+ fn_display_match_list(e, matches, (size_t)len, (size_t)max);
}
static const char *
@@ -1494,7 +1775,7 @@ _rl_completion_append_character_function(const char *dummy
__attribute__((__unused__)))
{
static char buf[2];
- buf[0] = rl_completion_append_character;
+ buf[0] = (char)rl_completion_append_character;
buf[1] = '\0';
return buf;
}
@@ -1507,6 +1788,10 @@ _rl_completion_append_character_function(const char *dummy
int
rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
{
+#ifdef WIDECHAR
+ static ct_buffer_t wbreak_conv, sprefix_conv;
+#endif
+
if (h == NULL || e == NULL)
rl_initialize();
@@ -1515,17 +1800,21 @@ rl_complete(int ignore __attribute__((__unused__)), int invoking_key)
arr[0] = (char)invoking_key;
arr[1] = '\0';
el_insertstr(e, arr);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
/* Just look at how many global variables modify this operation! */
return fn_complete(e,
(CPFunction *)rl_completion_entry_function,
rl_attempted_completion_function,
- rl_basic_word_break_characters, rl_special_prefixes,
- _rl_completion_append_character_function, rl_completion_query_items,
+ ct_decode_string(rl_basic_word_break_characters, &wbreak_conv),
+ ct_decode_string(rl_special_prefixes, &sprefix_conv),
+ _rl_completion_append_character_function,
+ (size_t)rl_completion_query_items,
&rl_completion_type, &rl_attempted_completion_over,
&rl_point, &rl_end);
+
+
}
@@ -1544,7 +1833,7 @@ _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
* bind key c to readline-type function func
*/
int
-rl_bind_key(int c, int func(int, int))
+rl_bind_key(int c, rl_command_func_t *func)
{
int retval = -1;
@@ -1556,7 +1845,7 @@ rl_bind_key(int c, int func(int, int))
e->el_map.key[c] = ED_INSERT;
retval = 0;
}
- return (retval);
+ return retval;
}
@@ -1572,7 +1861,7 @@ rl_read_key(void)
if (e == NULL || h == NULL)
rl_initialize();
- return (el_getc(e, fooarr));
+ return el_getc(e, fooarr);
}
@@ -1602,19 +1891,33 @@ rl_insert(int count, int c)
rl_initialize();
/* XXX - int -> char conversion can lose on multichars */
- arr[0] = c;
+ arr[0] = (char)c;
arr[1] = '\0';
for (; count > 0; count--)
el_push(e, arr);
- return (0);
+ return 0;
+}
+
+int
+rl_insert_text(const char *text)
+{
+ if (!text || *text == 0)
+ return 0;
+
+ if (h == NULL || e == NULL)
+ rl_initialize();
+
+ if (el_insertstr(e, text) < 0)
+ return 0;
+ return (int)strlen(text);
}
/*ARGSUSED*/
int
rl_newline(int count __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ int c __attribute__((__unused__)))
{
/*
* Readline-4.0 appears to ignore the args.
@@ -1675,7 +1978,7 @@ rl_callback_read_char()
} else
wbuf = NULL;
(*(void (*)(const char *))rl_linefunc)(wbuf);
- el_set(e, EL_UNBUFFERED, 1);
+ //el_set(e, EL_UNBUFFERED, 1);
}
}
@@ -1701,7 +2004,7 @@ void
rl_redisplay(void)
{
char a[2];
- a[0] = e->el_tty.t_c[TS_IO][C_REPRINT];
+ a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT];
a[1] = '\0';
el_push(e, a);
}
@@ -1710,7 +2013,7 @@ int
rl_get_previous_history(int count, int key)
{
char a[2];
- a[0] = key;
+ a[0] = (char)key;
a[1] = '\0';
while (count--)
el_push(e, a);
@@ -1733,7 +2036,7 @@ rl_deprep_terminal(void)
int
rl_read_init_file(const char *s)
{
- return(el_source(e, s));
+ return el_source(e, s);
}
int
@@ -1747,7 +2050,7 @@ rl_parse_and_bind(const char *line)
tok_str(tok, line, &argc, &argv);
argc = el_parse(e, argc, argv);
tok_end(tok);
- return (argc ? 1 : 0);
+ return argc ? 1 : 0;
}
int
@@ -1757,7 +2060,7 @@ rl_variable_bind(const char *var, const char *value)
* The proper return value is undocument, but this is what the
* readline source seems to do.
*/
- return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0);
+ return el_set(e, EL_BIND, "", var, value) == -1 ? 1 : 0;
}
void
@@ -1765,7 +2068,7 @@ rl_stuff_char(int c)
{
char buf[2];
- buf[0] = c;
+ buf[0] = (char)c;
buf[1] = '\0';
el_insertstr(e, buf);
}
@@ -1773,7 +2076,8 @@ rl_stuff_char(int c)
static int
_rl_event_read_char(EditLine *el, char *cp)
{
- int n, num_read = 0;
+ int n;
+ ssize_t num_read = 0;
*cp = '\0';
while (rl_event_hook) {
@@ -1782,23 +2086,23 @@ _rl_event_read_char(EditLine *el, char *cp)
#if defined(FIONREAD)
if (ioctl(el->el_infd, FIONREAD, &n) < 0)
- return(-1);
+ return -1;
if (n)
- num_read = read(el->el_infd, cp, 1);
+ num_read = read(el->el_infd, cp, (size_t)1);
else
num_read = 0;
#elif defined(F_SETFL) && defined(O_NDELAY)
if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
- return(-1);
+ return -1;
if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
- return(-1);
+ return -1;
num_read = read(el->el_infd, cp, 1);
if (fcntl(el->el_infd, F_SETFL, n))
- return(-1);
+ return -1;
#else
/* not non-blocking, but what you gonna do? */
num_read = read(el->el_infd, cp, 1);
- return(-1);
+ return -1;
#endif
if (num_read < 0 && errno == EAGAIN)
@@ -1809,7 +2113,7 @@ _rl_event_read_char(EditLine *el, char *cp)
}
if (!rl_event_hook)
el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
- return(num_read);
+ return (int)num_read;
}
static void
@@ -1817,8 +2121,8 @@ _rl_update_pos(void)
{
const LineInfo *li = el_line(e);
- rl_point = li->cursor - li->buffer;
- rl_end = li->lastchar - li->buffer;
+ rl_point = (int)(li->cursor - li->buffer);
+ rl_end = (int)(li->lastchar - li->buffer);
}
void
@@ -1848,18 +2152,18 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun)
len = 1;
max = 10;
- if ((list = malloc(max * sizeof(*list))) == NULL)
+ if ((list = el_malloc(max * sizeof(*list))) == NULL)
return NULL;
while ((match = (*fun)(str, (int)(len - 1))) != NULL) {
+ list[len++] = match;
if (len == max) {
char **nl;
max += 10;
- if ((nl = realloc(list, max * sizeof(*nl))) == NULL)
+ if ((nl = el_realloc(list, max * sizeof(*nl))) == NULL)
goto out;
list = nl;
}
- list[len++] = match;
}
if (len == 1)
goto out;
@@ -1883,7 +2187,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun)
if ((list[0] = strdup(str)) == NULL)
goto out;
} else {
- if ((list[0] = malloc(min + 1)) == NULL)
+ if ((list[0] = el_malloc((min + 1) * sizeof(*list[0]))) == NULL)
goto out;
(void)memcpy(list[0], list[1], min);
list[0][min] = '\0';
@@ -1891,7 +2195,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun)
return list;
out:
- free(list);
+ el_free(list);
return NULL;
}
@@ -1921,10 +2225,21 @@ _rl_qsort_string_compare(char **s1, char **s2)
return strcoll(*s1, *s2);
}
+HISTORY_STATE *
+history_get_history_state(void)
+{
+ HISTORY_STATE *hs;
+
+ if ((hs = el_malloc(sizeof(*hs))) == NULL)
+ return NULL;
+ hs->length = history_length;
+ return hs;
+}
+
int
/*ARGSUSED*/
rl_kill_text(int from __attribute__((__unused__)),
- int to __attribute__((__unused__)))
+ int to __attribute__((__unused__)))
{
return 0;
}
@@ -1950,9 +2265,9 @@ rl_set_keymap(Keymap k __attribute__((__unused__)))
int
/*ARGSUSED*/
rl_generic_bind(int type __attribute__((__unused__)),
- const char * keyseq __attribute__((__unused__)),
- const char * data __attribute__((__unused__)),
- Keymap k __attribute__((__unused__)))
+ const char * keyseq __attribute__((__unused__)),
+ const char * data __attribute__((__unused__)),
+ Keymap k __attribute__((__unused__)))
{
return 0;
}
@@ -1960,8 +2275,20 @@ rl_generic_bind(int type __attribute__((__unused__)),
int
/*ARGSUSED*/
rl_bind_key_in_map(int key __attribute__((__unused__)),
- Function *fun __attribute__((__unused__)),
- Keymap k __attribute__((__unused__)))
+ rl_command_func_t *fun __attribute__((__unused__)),
+ Keymap k __attribute__((__unused__)))
+{
+ return 0;
+}
+
+/* unsupported, but needed by python */
+void
+rl_cleanup_after_signal(void)
+{
+}
+
+int
+rl_on_new_line(void)
{
return 0;
}
diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h
index 0e300faed89..d9efe3e01a8 100644
--- a/cmd-line-utils/libedit/readline/readline.h
+++ b/cmd-line-utils/libedit/readline/readline.h
@@ -1,4 +1,4 @@
-/* $NetBSD: readline.h,v 1.24 2009/02/05 19:15:26 christos Exp $ */
+/* $NetBSD: readline.h,v 1.32 2010/09/16 20:08:52 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -32,6 +32,7 @@
#define _READLINE_H_
#include <sys/types.h>
+#include <stdio.h>
/* list of readline stuff supported by editline library's readline wrapper */
@@ -42,10 +43,18 @@ typedef void VCPFunction(char *);
typedef char *CPFunction(const char *, int);
typedef char **CPPFunction(const char *, int, int);
typedef char *rl_compentry_func_t(const char *, int);
+typedef int rl_command_func_t(int, int);
+
+/* only supports length */
+typedef struct {
+ int length;
+} HISTORY_STATE;
+
+typedef void *histdata_t;
typedef struct _hist_entry {
const char *line;
- const char *data;
+ histdata_t data;
} HIST_ENTRY;
typedef struct _keymap_entry {
@@ -79,12 +88,16 @@ typedef KEYMAP_ENTRY *Keymap;
#define RUBOUT 0x7f
#define ABORT_CHAR CTRL('G')
+#define RL_READLINE_VERSION 0x0402
+#define RL_PROMPT_START_IGNORE '\1'
+#define RL_PROMPT_END_IGNORE '\2'
/* global variables used by readline enabled applications */
#ifdef __cplusplus
extern "C" {
#endif
extern const char *rl_library_version;
+extern int rl_readline_version;
extern char *rl_readline_name;
extern FILE *rl_instream;
extern FILE *rl_outstream;
@@ -138,6 +151,7 @@ int where_history(void);
HIST_ENTRY *current_history(void);
HIST_ENTRY *history_get(int);
HIST_ENTRY *remove_history(int);
+HIST_ENTRY *replace_history_entry(int, const char *, histdata_t);
int history_total_bytes(void);
int history_set_pos(int);
HIST_ENTRY *previous_history(void);
@@ -147,6 +161,7 @@ int history_search_prefix(const char *, int);
int history_search_pos(const char *, int, int);
int read_history(const char *);
int write_history(const char *);
+int history_truncate_file (const char *, int);
int history_expand(char *, char **);
char **history_tokenize(const char *);
const char *get_history_event(const char *, int *, int);
@@ -161,8 +176,9 @@ char **completion_matches(const char *, CPFunction *);
void rl_display_match_list(char **, int, int);
int rl_insert(int, int);
+int rl_insert_text(const char *);
void rl_reset_terminal(const char *);
-int rl_bind_key(int, int (*)(int, int));
+int rl_bind_key(int, rl_command_func_t *);
int rl_newline(int, int);
void rl_callback_read_char(void);
void rl_callback_handler_install(const char *, VCPFunction *);
@@ -176,6 +192,7 @@ int rl_parse_and_bind(const char *);
int rl_variable_bind(const char *, const char *);
void rl_stuff_char(int);
int rl_add_defun(const char *, Function *, int);
+HISTORY_STATE *history_get_history_state(void);
void rl_get_screen_size(int *, int *);
void rl_set_screen_size(int, int);
char *rl_filename_completion_function (const char *, int);
@@ -184,6 +201,7 @@ int _rl_qsort_string_compare(char **, char **);
char **rl_completion_matches(const char *, rl_compentry_func_t *);
void rl_forced_update_display(void);
int rl_set_prompt(const char *);
+int rl_on_new_line(void);
/*
* The following are not implemented
@@ -193,7 +211,9 @@ Keymap rl_get_keymap(void);
void rl_set_keymap(Keymap);
Keymap rl_make_bare_keymap(void);
int rl_generic_bind(int, const char *, const char *, Keymap);
-int rl_bind_key_in_map(int, Function *, Keymap);
+int rl_bind_key_in_map(int, rl_command_func_t *, Keymap);
+void rl_cleanup_after_signal(void);
+void rl_free_line_state(void);
#ifdef __cplusplus
}
#endif
diff --git a/cmd-line-utils/libedit/refresh.c b/cmd-line-utils/libedit/refresh.c
index 5edd1fe78fc..64057eaabfe 100644
--- a/cmd-line-utils/libedit/refresh.c
+++ b/cmd-line-utils/libedit/refresh.c
@@ -1,4 +1,4 @@
-/* $NetBSD: refresh.c,v 1.28 2008/09/10 15:45:37 christos Exp $ */
+/* $NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -50,14 +50,15 @@ static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#include "el.h"
-private void re_addc(EditLine *, int);
-private void re_update_line(EditLine *, char *, char *, int);
-private void re_insert (EditLine *, char *, int, int, char *, int);
-private void re_delete(EditLine *, char *, int, int, int);
-private void re_fastputc(EditLine *, int);
+private void re_nextline(EditLine *);
+private void re_addc(EditLine *, Int);
+private void re_update_line(EditLine *, Char *, Char *, int);
+private void re_insert (EditLine *, Char *, int, int, Char *, int);
+private void re_delete(EditLine *, Char *, int, int, int);
+private void re_fastputc(EditLine *, Int);
private void re_clear_eol(EditLine *, int, int, int);
-private void re__strncopy(char *, char *, size_t);
-private void re__copy_and_pad(char *, const char *, size_t);
+private void re__strncopy(Char *, Char *, size_t);
+private void re__copy_and_pad(Char *, const Char *, size_t);
#ifdef DEBUG_REFRESH
private void re_printstr(EditLine *, const char *, char *, char *);
@@ -87,45 +88,70 @@ re_printstr(EditLine *el, const char *str, char *f, char *t)
#define ELRE_DEBUG(a, b)
#endif
+/* re_nextline():
+ * Move to the next line or scroll
+ */
+private void
+re_nextline(EditLine *el)
+{
+ el->el_refresh.r_cursor.h = 0; /* reset it. */
+
+ /*
+ * If we would overflow (input is longer than terminal size),
+ * emulate scroll by dropping first line and shuffling the rest.
+ * We do this via pointer shuffling - it's safe in this case
+ * and we avoid memcpy().
+ */
+ if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) {
+ int i, lins = el->el_terminal.t_size.v;
+ Char *firstline = el->el_vdisplay[0];
+
+ for(i = 1; i < lins; i++)
+ el->el_vdisplay[i - 1] = el->el_vdisplay[i];
+
+ firstline[0] = '\0'; /* empty the string */
+ el->el_vdisplay[i - 1] = firstline;
+ } else
+ el->el_refresh.r_cursor.v++;
+
+ ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_terminal.t_size.v,
+ (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
+ el->el_refresh.r_cursor.v, el->el_terminal.t_size.v),
+ abort());
+}
/* re_addc():
* Draw c, expanding tabs, control chars etc.
*/
private void
-re_addc(EditLine *el, int c)
+re_addc(EditLine *el, Int c)
{
-
- if (el_isprint(c)) {
- re_putc(el, c, 1);
- return;
- }
- if (c == '\n') { /* expand the newline */
- int oldv = el->el_refresh.r_cursor.v;
- re_putc(el, '\0', 0); /* assure end of line */
- if (oldv == el->el_refresh.r_cursor.v) { /* XXX */
- el->el_refresh.r_cursor.h = 0; /* reset cursor pos */
- el->el_refresh.r_cursor.v++;
- }
- return;
- }
- if (c == '\t') { /* expand the tab */
+ switch (ct_chr_class((Char)c)) {
+ case CHTYPE_TAB: /* expand the tab */
for (;;) {
re_putc(el, ' ', 1);
if ((el->el_refresh.r_cursor.h & 07) == 0)
break; /* go until tab stop */
}
- } else if (iscntrl(c)) {
- re_putc(el, '^', 1);
- if (c == '\177')
- re_putc(el, '?', 1);
- else
- /* uncontrolify it; works only for iso8859-1 like sets */
- re_putc(el, (c | 0100), 1);
- } else {
- re_putc(el, '\\', 1);
- re_putc(el, (int) ((((unsigned int) c >> 6) & 07) + '0'), 1);
- re_putc(el, (int) ((((unsigned int) c >> 3) & 07) + '0'), 1);
- re_putc(el, (c & 07) + '0', 1);
+ break;
+ case CHTYPE_NL: {
+ int oldv = el->el_refresh.r_cursor.v;
+ re_putc(el, '\0', 0); /* assure end of line */
+ if (oldv == el->el_refresh.r_cursor.v) /* XXX */
+ re_nextline(el);
+ break;
+ }
+ case CHTYPE_PRINT:
+ re_putc(el, c, 1);
+ break;
+ default: {
+ Char visbuf[VISUAL_WIDTH_MAX];
+ ssize_t i, n =
+ ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
+ for (i = 0; n-- > 0; ++i)
+ re_putc(el, visbuf[i], 1);
+ break;
+ }
}
}
@@ -134,43 +160,31 @@ re_addc(EditLine *el, int c)
* Draw the character given
*/
protected void
-re_putc(EditLine *el, int c, int shift)
+re_putc(EditLine *el, Int c, int shift)
{
+ int i, w = Width(c);
+ ELRE_DEBUG(1, (__F, "printing %5x '%c'\r\n", c, c));
+
+ while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h))
+ re_putc(el, ' ', 1);
- ELRE_DEBUG(1, (__F, "printing %3.3o '%c'\r\n", c, c));
+ el->el_vdisplay[el->el_refresh.r_cursor.v]
+ [el->el_refresh.r_cursor.h] = c;
+ /* assumes !shift is only used for single-column chars */
+ i = w;
+ while (--i > 0)
+ el->el_vdisplay[el->el_refresh.r_cursor.v]
+ [el->el_refresh.r_cursor.h + i] = MB_FILL_CHAR;
- el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c;
if (!shift)
return;
- el->el_refresh.r_cursor.h++; /* advance to next place */
- if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
- el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0';
+ el->el_refresh.r_cursor.h += w; /* advance to next place */
+ if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) {
/* assure end of line */
- el->el_refresh.r_cursor.h = 0; /* reset it. */
-
- /*
- * If we would overflow (input is longer than terminal size),
- * emulate scroll by dropping first line and shuffling the rest.
- * We do this via pointer shuffling - it's safe in this case
- * and we avoid memcpy().
- */
- if (el->el_refresh.r_cursor.v + 1 >= el->el_term.t_size.v) {
- int i, lins = el->el_term.t_size.v;
- char *firstline = el->el_vdisplay[0];
-
- for(i=1; i < lins; i++)
- el->el_vdisplay[i-1] = el->el_vdisplay[i];
-
- firstline[0] = '\0'; /* empty the string */
- el->el_vdisplay[i-1] = firstline;
- } else
- el->el_refresh.r_cursor.v++;
-
- ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
- (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
- el->el_refresh.r_cursor.v, el->el_term.t_size.v),
- abort());
+ el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h]
+ = '\0';
+ re_nextline(el);
}
}
@@ -185,7 +199,7 @@ protected void
re_refresh(EditLine *el)
{
int i, rhdiff;
- char *cp, *st;
+ Char *cp, *st;
coord_t cur;
#ifdef notyet
size_t termsz;
@@ -220,7 +234,7 @@ re_refresh(EditLine *el)
/* draw the current input buffer */
#if notyet
- termsz = el->el_term.t_size.h * el->el_term.t_size.v;
+ termsz = el->el_terminal.t_size.h * el->el_terminal.t_size.v;
if (el->el_line.lastchar - el->el_line.buffer > termsz) {
/*
* If line is longer than terminal, process only part
@@ -229,26 +243,33 @@ re_refresh(EditLine *el)
size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;
st = el->el_line.lastchar - rem
- - (termsz - (((rem / el->el_term.t_size.v) - 1)
- * el->el_term.t_size.v));
+ - (termsz - (((rem / el->el_terminal.t_size.v) - 1)
+ * el->el_terminal.t_size.v));
} else
#endif
st = el->el_line.buffer;
for (cp = st; cp < el->el_line.lastchar; cp++) {
if (cp == el->el_line.cursor) {
+ int w = Width(*cp);
/* save for later */
cur.h = el->el_refresh.r_cursor.h;
cur.v = el->el_refresh.r_cursor.v;
+ /* handle being at a linebroken doublewidth char */
+ if (w > 1 && el->el_refresh.r_cursor.h + w >
+ el->el_terminal.t_size.h) {
+ cur.h = 0;
+ cur.v++;
+ }
}
- re_addc(el, (unsigned char) *cp);
+ re_addc(el, *cp);
}
if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */
cur.h = el->el_refresh.r_cursor.h;
cur.v = el->el_refresh.r_cursor.v;
}
- rhdiff = el->el_term.t_size.h - el->el_refresh.r_cursor.h -
+ rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h -
el->el_rprompt.p_pos.h;
if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
!el->el_refresh.r_cursor.v && rhdiff > 1) {
@@ -271,8 +292,8 @@ re_refresh(EditLine *el)
ELRE_DEBUG(1, (__F,
"term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
- el->el_term.t_size.h, el->el_refresh.r_cursor.h,
- el->el_refresh.r_cursor.v, el->el_vdisplay[0]));
+ el->el_terminal.t_size.h, el->el_refresh.r_cursor.h,
+ el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0])));
ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
for (i = 0; i <= el->el_refresh.r_newcv; i++) {
@@ -287,7 +308,7 @@ re_refresh(EditLine *el)
* leftover stuff.
*/
re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
- (size_t) el->el_term.t_size.h);
+ (size_t) el->el_terminal.t_size.h);
}
ELRE_DEBUG(1, (__F,
"\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
@@ -295,11 +316,12 @@ re_refresh(EditLine *el)
if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
for (; i <= el->el_refresh.r_oldcv; i++) {
- term_move_to_line(el, i);
- term_move_to_char(el, 0);
- term_clear_EOL(el, (int) strlen(el->el_display[i]));
+ terminal_move_to_line(el, i);
+ terminal_move_to_char(el, 0);
+ /* This Strlen should be safe even with MB_FILL_CHARs */
+ terminal_clear_EOL(el, (int) Strlen(el->el_display[i]));
#ifdef DEBUG_REFRESH
- term_overwrite(el, "C\b", 2);
+ terminal_overwrite(el, "C\b", (size_t)2);
#endif /* DEBUG_REFRESH */
el->el_display[i][0] = '\0';
}
@@ -309,8 +331,8 @@ re_refresh(EditLine *el)
"\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
cur.h, cur.v));
- term_move_to_line(el, cur.v); /* go to where the cursor is */
- term_move_to_char(el, cur.h);
+ terminal_move_to_line(el, cur.v); /* go to where the cursor is */
+ terminal_move_to_char(el, cur.h);
}
@@ -321,10 +343,10 @@ protected void
re_goto_bottom(EditLine *el)
{
- term_move_to_line(el, el->el_refresh.r_oldcv);
- term__putc(el, '\n');
+ terminal_move_to_line(el, el->el_refresh.r_oldcv);
+ terminal__putc(el, '\n');
re_clear_display(el);
- term__flush(el);
+ terminal__flush(el);
}
@@ -335,9 +357,9 @@ re_goto_bottom(EditLine *el)
private void
/*ARGSUSED*/
re_insert(EditLine *el __attribute__((__unused__)),
- char *d, int dat, int dlen, char *s, int num)
+ Char *d, int dat, int dlen, Char *s, int num)
{
- char *a, *b;
+ Char *a, *b;
if (num <= 0)
return;
@@ -346,8 +368,8 @@ re_insert(EditLine *el __attribute__((__unused__)),
ELRE_DEBUG(1,
(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d));
- ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
+ num, dat, dlen, ct_encode_string(d)));
+ ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
/* open up the space for num chars */
if (num > 0) {
@@ -357,19 +379,24 @@ re_insert(EditLine *el __attribute__((__unused__)),
*b-- = *a--;
d[dlen] = '\0'; /* just in case */
}
+
ELRE_DEBUG(1, (__F,
"re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d));
- ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
+ num, dat, dlen, ct_encode_string(d)));
+ ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
/* copy the characters */
for (a = d + dat; (a < d + dlen) && (num > 0); num--)
*a++ = *s++;
+#ifdef notyet
+ /* ct_encode_string() uses a static buffer, so we can't conveniently
+ * encode both d & s here */
ELRE_DEBUG(1,
(__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
num, dat, dlen, d, s));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
+#endif
}
@@ -379,9 +406,9 @@ re_insert(EditLine *el __attribute__((__unused__)),
private void
/*ARGSUSED*/
re_delete(EditLine *el __attribute__((__unused__)),
- char *d, int dat, int dlen, int num)
+ Char *d, int dat, int dlen, int num)
{
- char *a, *b;
+ Char *a, *b;
if (num <= 0)
return;
@@ -391,7 +418,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
}
ELRE_DEBUG(1,
(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d));
+ num, dat, dlen, ct_encode_string(d)));
/* open up the space for num chars */
if (num > 0) {
@@ -403,7 +430,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
}
ELRE_DEBUG(1,
(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
- num, dat, dlen, d));
+ num, dat, dlen, ct_encode_string(d)));
}
@@ -411,7 +438,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
* Like strncpy without padding.
*/
private void
-re__strncopy(char *a, char *b, size_t n)
+re__strncopy(Char *a, Char *b, size_t n)
{
while (n-- && *b)
@@ -422,7 +449,7 @@ re__strncopy(char *a, char *b, size_t n)
* Find the number of characters we need to clear till the end of line
* in order to make sure that we have cleared the previous contents of
* the line. fx and sx is the number of characters inserted or deleted
- * int the first or second diff, diff is the difference between the
+ * in the first or second diff, diff is the difference between the
* number of characters between the new and old line.
*/
private void
@@ -442,7 +469,7 @@ re_clear_eol(EditLine *el, int fx, int sx, int diff)
diff = sx;
ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff));
- term_clear_EOL(el, diff);
+ terminal_clear_EOL(el, diff);
}
/*****************************************************************
@@ -470,12 +497,13 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
#define MIN_END_KEEP 4
private void
-re_update_line(EditLine *el, char *old, char *new, int i)
+re_update_line(EditLine *el, Char *old, Char *new, int i)
{
- char *o, *n, *p, c;
- char *ofd, *ols, *oe, *nfd, *nls, *ne;
- char *osb, *ose, *nsb, *nse;
+ Char *o, *n, *p, c;
+ Char *ofd, *ols, *oe, *nfd, *nls, *ne;
+ Char *osb, *ose, *nsb, *nse;
int fx, sx;
+ size_t len;
/*
* find first diff
@@ -602,12 +630,12 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* fx is the number of characters we need to insert/delete: in the
* beginning to bring the two same begins together
*/
- fx = (nsb - nfd) - (osb - ofd);
+ fx = (int)((nsb - nfd) - (osb - ofd));
/*
* sx is the number of characters we need to insert/delete: in the
* end to bring the two same last parts together
*/
- sx = (nls - nse) - (ols - ose);
+ sx = (int)((nls - nse) - (ols - ose));
if (!EL_CAN_INSERT) {
if (fx > 0) {
@@ -656,8 +684,8 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* Now that we are done with pragmatics we recompute fx, sx
*/
- fx = (nsb - nfd) - (osb - ofd);
- sx = (nls - nse) - (ols - ose);
+ fx = (int)((nsb - nfd) - (osb - ofd));
+ sx = (int)((nls - nse) - (ols - ose));
ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx));
ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
@@ -688,7 +716,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* don't have to change the line, we don't move to it. el_cursor.h to
* first diff char
*/
- term_move_to_line(el, i);
+ terminal_move_to_line(el, i);
/*
* at this point we have something like this:
@@ -712,7 +740,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* if we have a net insert on the first difference, AND inserting the
* net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful
* character (which is ne if nls != ne, otherwise is nse) off the edge
- * of the screen (el->el_term.t_size.h) else we do the deletes first
+ * of the screen (el->el_terminal.t_size.h) else we do the deletes first
* so that we keep everything we need to.
*/
@@ -734,13 +762,13 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* No insert or delete
*/
if ((nsb != nfd) && fx > 0 &&
- ((p - old) + fx <= el->el_term.t_size.h)) {
+ ((p - old) + fx <= el->el_terminal.t_size.h)) {
ELRE_DEBUG(1,
(__F, "first diff insert at %d...\r\n", nfd - new));
/*
* Move to the first char to insert, where the first diff is.
*/
- term_move_to_char(el, nfd - new);
+ terminal_move_to_char(el, (int)(nfd - new));
/*
* Check if we have stuff to keep at end
*/
@@ -752,21 +780,22 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (fx > 0) {
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in early first diff\n"));
- term_insertwrite(el, nfd, fx);
- re_insert(el, old, ofd - old,
- el->el_term.t_size.h, nfd, fx);
+ terminal_insertwrite(el, nfd, fx);
+ re_insert(el, old, (int)(ofd - old),
+ el->el_terminal.t_size.h, nfd, fx);
}
/*
* write (nsb-nfd) - fx chars of new starting at
* (nfd + fx)
*/
- term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
- re__strncopy(ofd + fx, nfd + fx,
- (size_t) ((nsb - nfd) - fx));
+ len = (size_t) ((nsb - nfd) - fx);
+ terminal_overwrite(el, (nfd + fx), len);
+ re__strncopy(ofd + fx, nfd + fx, len);
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
- term_overwrite(el, nfd, (nsb - nfd));
- re__strncopy(ofd, nfd, (size_t) (nsb - nfd));
+ len = (size_t)(nsb - nfd);
+ terminal_overwrite(el, nfd, len);
+ re__strncopy(ofd, nfd, len);
/*
* Done
*/
@@ -778,7 +807,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* move to the first char to delete where the first diff is
*/
- term_move_to_char(el, ofd - old);
+ terminal_move_to_char(el, (int)(ofd - old));
/*
* Check if we have stuff to save
*/
@@ -791,15 +820,16 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (fx < 0) {
ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in first diff\n"));
- term_deletechars(el, -fx);
- re_delete(el, old, ofd - old,
- el->el_term.t_size.h, -fx);
+ terminal_deletechars(el, -fx);
+ re_delete(el, old, (int)(ofd - old),
+ el->el_terminal.t_size.h, -fx);
}
/*
* write (nsb-nfd) chars of new starting at nfd
*/
- term_overwrite(el, nfd, (nsb - nfd));
- re__strncopy(ofd, nfd, (size_t) (nsb - nfd));
+ len = (size_t) (nsb - nfd);
+ terminal_overwrite(el, nfd, len);
+ re__strncopy(ofd, nfd, len);
} else {
ELRE_DEBUG(1, (__F,
@@ -807,8 +837,9 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* write (nsb-nfd) chars of new starting at nfd
*/
- term_overwrite(el, nfd, (nsb - nfd));
- re_clear_eol(el, fx, sx, (oe - old) - (ne - new));
+ terminal_overwrite(el, nfd, (size_t)(nsb - nfd));
+ re_clear_eol(el, fx, sx,
+ (int)((oe - old) - (ne - new)));
/*
* Done
*/
@@ -817,7 +848,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
} else
fx = 0;
- if (sx < 0 && (ose - old) + fx < el->el_term.t_size.h) {
+ if (sx < 0 && (ose - old) + fx < el->el_terminal.t_size.h) {
ELRE_DEBUG(1, (__F,
"second diff delete at %d...\r\n", (ose - old) + fx));
/*
@@ -827,7 +858,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* fx is the number of characters inserted (+) or deleted (-)
*/
- term_move_to_char(el, (ose - old) + fx);
+ terminal_move_to_char(el, (int)((ose - old) + fx));
/*
* Check if we have stuff to save
*/
@@ -839,17 +870,18 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (sx < 0) {
ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in second diff\n"));
- term_deletechars(el, -sx);
+ terminal_deletechars(el, -sx);
}
/*
* write (nls-nse) chars of new starting at nse
*/
- term_overwrite(el, nse, (nls - nse));
+ terminal_overwrite(el, nse, (size_t)(nls - nse));
} else {
ELRE_DEBUG(1, (__F,
"but with nothing left to save\r\n"));
- term_overwrite(el, nse, (nls - nse));
- re_clear_eol(el, fx, sx, (oe - old) - (ne - new));
+ terminal_overwrite(el, nse, (size_t)(nls - nse));
+ re_clear_eol(el, fx, sx,
+ (int)((oe - old) - (ne - new)));
}
}
/*
@@ -859,7 +891,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
nfd - new));
- term_move_to_char(el, nfd - new);
+ terminal_move_to_char(el, (int)(nfd - new));
/*
* Check if we have stuff to keep at the end
*/
@@ -870,28 +902,29 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* to zero above as a flag saying that we hadn't done
* an early first insert.
*/
- fx = (nsb - nfd) - (osb - ofd);
+ fx = (int)((nsb - nfd) - (osb - ofd));
if (fx > 0) {
/*
* insert fx chars of new starting at nfd
*/
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in late first diff\n"));
- term_insertwrite(el, nfd, fx);
- re_insert(el, old, ofd - old,
- el->el_term.t_size.h, nfd, fx);
+ terminal_insertwrite(el, nfd, fx);
+ re_insert(el, old, (int)(ofd - old),
+ el->el_terminal.t_size.h, nfd, fx);
}
/*
* write (nsb-nfd) - fx chars of new starting at
* (nfd + fx)
*/
- term_overwrite(el, nfd + fx, (nsb - nfd) - fx);
- re__strncopy(ofd + fx, nfd + fx,
- (size_t) ((nsb - nfd) - fx));
+ len = (size_t) ((nsb - nfd) - fx);
+ terminal_overwrite(el, (nfd + fx), len);
+ re__strncopy(ofd + fx, nfd + fx, len);
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
- term_overwrite(el, nfd, (nsb - nfd));
- re__strncopy(ofd, nfd, (size_t) (nsb - nfd));
+ len = (size_t) (nsb - nfd);
+ terminal_overwrite(el, nfd, len);
+ re__strncopy(ofd, nfd, len);
}
}
/*
@@ -899,24 +932,25 @@ re_update_line(EditLine *el, char *old, char *new, int i)
*/
if (sx >= 0) {
ELRE_DEBUG(1, (__F,
- "second diff insert at %d...\r\n", nse - new));
- term_move_to_char(el, nse - new);
+ "second diff insert at %d...\r\n", (int)(nse - new)));
+ terminal_move_to_char(el, (int)(nse - new));
if (ols != oe) {
ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
if (sx > 0) {
/* insert sx chars of new starting at nse */
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in second diff\n"));
- term_insertwrite(el, nse, sx);
+ terminal_insertwrite(el, nse, sx);
}
/*
* write (nls-nse) - sx chars of new starting at
* (nse + sx)
*/
- term_overwrite(el, nse + sx, (nls - nse) - sx);
+ terminal_overwrite(el, (nse + sx),
+ (size_t)((nls - nse) - sx));
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
- term_overwrite(el, nse, (nls - nse));
+ terminal_overwrite(el, nse, (size_t)(nls - nse));
/*
* No need to do a clear-to-end here because we were
@@ -933,7 +967,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* Copy string and pad with spaces
*/
private void
-re__copy_and_pad(char *dst, const char *src, size_t width)
+re__copy_and_pad(Char *dst, const Char *src, size_t width)
{
size_t i;
@@ -956,8 +990,8 @@ re__copy_and_pad(char *dst, const char *src, size_t width)
protected void
re_refresh_cursor(EditLine *el)
{
- char *cp, c;
- int h, v, th;
+ Char *cp;
+ int h, v, th, w;
if (el->el_line.cursor >= el->el_line.lastchar) {
if (el->el_map.current == el->el_map.alt
@@ -970,47 +1004,46 @@ re_refresh_cursor(EditLine *el)
/* first we must find where the cursor is... */
h = el->el_prompt.p_pos.h;
v = el->el_prompt.p_pos.v;
- th = el->el_term.t_size.h; /* optimize for speed */
+ th = el->el_terminal.t_size.h; /* optimize for speed */
/* do input buffer to el->el_line.cursor */
for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
- c = *cp;
- h++; /* all chars at least this long */
-
- if (c == '\n') {/* handle newline in data part too */
+ switch (ct_chr_class(*cp)) {
+ case CHTYPE_NL: /* handle newline in data part too */
h = 0;
v++;
- } else {
- if (c == '\t') { /* if a tab, to next tab stop */
- while (h & 07) {
- h++;
- }
- } else if (iscntrl((unsigned char) c)) {
- /* if control char */
- h++;
- if (h > th) { /* if overflow, compensate */
- h = 1;
- v++;
- }
- } else if (!el_isprint((unsigned char) c)) {
- h += 3;
- if (h > th) { /* if overflow, compensate */
- h = h - th;
- v++;
- }
+ break;
+ case CHTYPE_TAB: /* if a tab, to next tab stop */
+ while (++h & 07)
+ continue;
+ break;
+ default:
+ w = Width(*cp);
+ if (w > 1 && h + w > th) { /* won't fit on line */
+ h = 0;
+ v++;
}
- }
+ h += ct_visual_width(*cp);
+ break;
+ }
if (h >= th) { /* check, extra long tabs picked up here also */
- h = 0;
+ h -= th;
v++;
}
}
+ /* if we have a next character, and it's a doublewidth one, we need to
+ * check whether we need to linebreak for it to fit */
+ if (cp < el->el_line.lastchar && (w = Width(*cp)) > 1)
+ if (h + w > th) {
+ h = 0;
+ v++;
+ }
/* now go there */
- term_move_to_line(el, v);
- term_move_to_char(el, h);
- term__flush(el);
+ terminal_move_to_line(el, v);
+ terminal_move_to_char(el, h);
+ terminal__flush(el);
}
@@ -1018,12 +1051,19 @@ re_refresh_cursor(EditLine *el)
* Add a character fast.
*/
private void
-re_fastputc(EditLine *el, int c)
+re_fastputc(EditLine *el, Int c)
{
+ int w = Width((Char)c);
+ while (w > 1 && el->el_cursor.h + w > el->el_terminal.t_size.h)
+ re_fastputc(el, ' ');
- term__putc(el, c);
+ terminal__putc(el, c);
el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
- if (el->el_cursor.h >= el->el_term.t_size.h) {
+ while (--w > 0)
+ el->el_display[el->el_cursor.v][el->el_cursor.h++]
+ = MB_FILL_CHAR;
+
+ if (el->el_cursor.h >= el->el_terminal.t_size.h) {
/* if we must overflow */
el->el_cursor.h = 0;
@@ -1033,27 +1073,27 @@ re_fastputc(EditLine *el, int c)
* We do this via pointer shuffling - it's safe in this case
* and we avoid memcpy().
*/
- if (el->el_cursor.v + 1 >= el->el_term.t_size.v) {
- int i, lins = el->el_term.t_size.v;
- char *firstline = el->el_display[0];
+ if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
+ int i, lins = el->el_terminal.t_size.v;
+ Char *firstline = el->el_display[0];
- for(i=1; i < lins; i++)
- el->el_display[i-1] = el->el_display[i];
+ for(i = 1; i < lins; i++)
+ el->el_display[i - 1] = el->el_display[i];
- re__copy_and_pad(firstline, "", 0);
- el->el_display[i-1] = firstline;
+ re__copy_and_pad(firstline, STR(""), (size_t)0);
+ el->el_display[i - 1] = firstline;
} else {
el->el_cursor.v++;
el->el_refresh.r_oldcv++;
}
if (EL_HAS_AUTO_MARGINS) {
if (EL_HAS_MAGIC_MARGINS) {
- term__putc(el, ' ');
- term__putc(el, '\b');
+ terminal__putc(el, ' ');
+ terminal__putc(el, '\b');
}
} else {
- term__putc(el, '\r');
- term__putc(el, '\n');
+ terminal__putc(el, '\r');
+ terminal__putc(el, '\n');
}
}
}
@@ -1066,7 +1106,7 @@ re_fastputc(EditLine *el, int c)
protected void
re_fastaddc(EditLine *el)
{
- char c;
+ Char c;
int rhdiff;
c = el->el_line.cursor[-1];
@@ -1075,25 +1115,30 @@ re_fastaddc(EditLine *el)
re_refresh(el); /* too hard to handle */
return;
}
- rhdiff = el->el_term.t_size.h - el->el_cursor.h -
+ rhdiff = el->el_terminal.t_size.h - el->el_cursor.h -
el->el_rprompt.p_pos.h;
if (el->el_rprompt.p_pos.h && rhdiff < 3) {
re_refresh(el); /* clear out rprompt if less than 1 char gap */
return;
} /* else (only do at end of line, no TAB) */
- if (iscntrl((unsigned char) c)) { /* if control char, do caret */
- char mc = (c == '\177') ? '?' : (c | 0100);
- re_fastputc(el, '^');
- re_fastputc(el, mc);
- } else if (el_isprint((unsigned char) c)) { /* normal char */
+ switch (ct_chr_class(c)) {
+ case CHTYPE_TAB: /* already handled, should never happen here */
+ break;
+ case CHTYPE_NL:
+ case CHTYPE_PRINT:
re_fastputc(el, c);
- } else {
- re_fastputc(el, '\\');
- re_fastputc(el, (int)(((((unsigned int)c) >> 6) & 3) + '0'));
- re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0'));
- re_fastputc(el, (c & 7) + '0');
+ break;
+ case CHTYPE_ASCIICTL:
+ case CHTYPE_NONPRINT: {
+ Char visbuf[VISUAL_WIDTH_MAX];
+ ssize_t i, n =
+ ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
+ for (i = 0; n-- > 0; ++i)
+ re_fastputc(el, visbuf[i]);
+ break;
+ }
}
- term__flush(el);
+ terminal__flush(el);
}
@@ -1107,7 +1152,7 @@ re_clear_display(EditLine *el)
el->el_cursor.v = 0;
el->el_cursor.h = 0;
- for (i = 0; i < el->el_term.t_size.v; i++)
+ for (i = 0; i < el->el_terminal.t_size.v; i++)
el->el_display[i][0] = '\0';
el->el_refresh.r_oldcv = 0;
}
@@ -1122,17 +1167,16 @@ re_clear_lines(EditLine *el)
if (EL_CAN_CEOL) {
int i;
- term_move_to_char(el, 0);
- for (i = 0; i <= el->el_refresh.r_oldcv; i++) {
+ for (i = el->el_refresh.r_oldcv; i >= 0; i--) {
/* for each line on the screen */
- term_move_to_line(el, i);
- term_clear_EOL(el, el->el_term.t_size.h);
+ terminal_move_to_line(el, i);
+ terminal_move_to_char(el, 0);
+ terminal_clear_EOL(el, el->el_terminal.t_size.h);
}
- term_move_to_line(el, 0);
} else {
- term_move_to_line(el, el->el_refresh.r_oldcv);
+ terminal_move_to_line(el, el->el_refresh.r_oldcv);
/* go to last line */
- term__putc(el, '\r'); /* go to BOL */
- term__putc(el, '\n'); /* go to new line */
+ terminal__putc(el, '\r'); /* go to BOL */
+ terminal__putc(el, '\n'); /* go to new line */
}
}
diff --git a/cmd-line-utils/libedit/refresh.h b/cmd-line-utils/libedit/refresh.h
index dd2bd02094b..f80be463545 100644
--- a/cmd-line-utils/libedit/refresh.h
+++ b/cmd-line-utils/libedit/refresh.h
@@ -1,4 +1,4 @@
-/* $NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */
+/* $NetBSD: refresh.h,v 1.6 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -48,7 +48,7 @@ typedef struct {
int r_newcv;
} el_refresh_t;
-protected void re_putc(EditLine *, int, int);
+protected void re_putc(EditLine *, Int, int);
protected void re_clear_lines(EditLine *);
protected void re_clear_display(EditLine *);
protected void re_refresh(EditLine *);
diff --git a/cmd-line-utils/libedit/search.c b/cmd-line-utils/libedit/search.c
index df50c7e7370..2324cc94d76 100644
--- a/cmd-line-utils/libedit/search.c
+++ b/cmd-line-utils/libedit/search.c
@@ -1,4 +1,4 @@
-/* $NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $ */
+/* $NetBSD: search.c,v 1.30 2011/10/04 15:27:04 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -65,15 +65,16 @@ protected int
search_init(EditLine *el)
{
- el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ);
+ el->el_search.patbuf = el_malloc(EL_BUFSIZ *
+ sizeof(*el->el_search.patbuf));
if (el->el_search.patbuf == NULL)
- return (-1);
+ return -1;
el->el_search.patlen = 0;
el->el_search.patdir = -1;
el->el_search.chacha = '\0';
el->el_search.chadir = CHAR_FWD;
el->el_search.chatflg = 0;
- return (0);
+ return 0;
}
@@ -84,7 +85,7 @@ protected void
search_end(EditLine *el)
{
- el_free((ptr_t) el->el_search.patbuf);
+ el_free(el->el_search.patbuf);
el->el_search.patbuf = NULL;
}
@@ -105,8 +106,11 @@ regerror(const char *msg)
* Return if string matches pattern
*/
protected int
-el_match(const char *str, const char *pat)
+el_match(const Char *str, const Char *pat)
{
+#ifdef WIDECHAR
+ static ct_buffer_t conv;
+#endif
#if defined (REGEX)
regex_t re;
int rv;
@@ -118,30 +122,31 @@ el_match(const char *str, const char *pat)
extern int re_exec(const char *);
#endif
- if (strstr(str, pat) != NULL)
- return (1);
+ if (Strstr(str, pat) != 0)
+ return 1;
#if defined(REGEX)
- if (regcomp(&re, pat, 0) == 0) {
- rv = regexec(&re, str, 0, NULL, 0) == 0;
+ if (regcomp(&re, ct_encode_string(pat, &conv), 0) == 0) {
+ rv = regexec(&re, ct_encode_string(str, &conv), (size_t)0, NULL,
+ 0) == 0;
regfree(&re);
} else {
rv = 0;
}
- return (rv);
+ return rv;
#elif defined(REGEXP)
- if ((re = regcomp(pat)) != NULL) {
- rv = regexec(re, str);
- free((ptr_t) re);
+ if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL) {
+ rv = regexec(re, ct_encode_string(str, &conv));
+ el_free(re);
} else {
rv = 0;
}
- return (rv);
+ return rv;
#else
- if (re_comp(pat) != NULL)
- return (0);
+ if (re_comp(ct_encode_string(pat, &conv)) != NULL)
+ return 0;
else
- return (re_exec(str) == 1);
+ return re_exec(ct_encode_string(str, &conv) == 1);
#endif
}
@@ -150,14 +155,14 @@ el_match(const char *str, const char *pat)
* return True if the pattern matches the prefix
*/
protected int
-c_hmatch(EditLine *el, const char *str)
+c_hmatch(EditLine *el, const Char *str)
{
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
el->el_search.patbuf, str);
#endif /* SDEBUG */
- return (el_match(str, el->el_search.patbuf));
+ return el_match(str, el->el_search.patbuf);
}
@@ -169,15 +174,16 @@ c_setpat(EditLine *el)
{
if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY &&
el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) {
- el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer;
+ el->el_search.patlen =
+ (size_t)(EL_CURSOR(el) - el->el_line.buffer);
if (el->el_search.patlen >= EL_BUFSIZ)
el->el_search.patlen = EL_BUFSIZ - 1;
if (el->el_search.patlen != 0) {
- (void) strncpy(el->el_search.patbuf, el->el_line.buffer,
+ (void) Strncpy(el->el_search.patbuf, el->el_line.buffer,
el->el_search.patlen);
el->el_search.patbuf[el->el_search.patlen] = '\0';
} else
- el->el_search.patlen = strlen(el->el_search.patbuf);
+ el->el_search.patlen = Strlen(el->el_search.patbuf);
}
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "\neventno = %d\n",
@@ -198,23 +204,24 @@ c_setpat(EditLine *el)
protected el_action_t
ce_inc_search(EditLine *el, int dir)
{
- static const char STRfwd[] = {'f', 'w', 'd', '\0'},
+ static const Char STRfwd[] = {'f', 'w', 'd', '\0'},
STRbck[] = {'b', 'c', 'k', '\0'};
- static char pchar = ':';/* ':' = normal, '?' = failed */
- static char endcmd[2] = {'\0', '\0'};
- char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
- const char *cp;
+ static Char pchar = ':';/* ':' = normal, '?' = failed */
+ static Char endcmd[2] = {'\0', '\0'};
+ Char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
+ const Char *cp;
el_action_t ret = CC_NORM;
int ohisteventno = el->el_history.eventno;
- int oldpatlen = el->el_search.patlen;
+ size_t oldpatlen = el->el_search.patlen;
int newdir = dir;
int done, redo;
- if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 +
+ if (el->el_line.lastchar + sizeof(STRfwd) /
+ sizeof(*el->el_line.lastchar) + 2 +
el->el_search.patlen >= el->el_line.limit)
- return (CC_ERROR);
+ return CC_ERROR;
for (;;) {
@@ -241,14 +248,14 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.lastchar = '\0';
re_refresh(el);
- if (el_getc(el, &ch) != 1)
- return (ed_end_of_file(el, 0));
+ if (FUN(el,getc)(el, &ch) != 1)
+ return ed_end_of_file(el, 0);
switch (el->el_map.current[(unsigned char) ch]) {
case ED_INSERT:
case ED_DIGIT:
if (el->el_search.patlen >= EL_BUFSIZ - LEN)
- term_beep(el);
+ terminal_beep(el);
else {
el->el_search.patbuf[el->el_search.patlen++] =
ch;
@@ -273,7 +280,7 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_search.patlen > LEN)
done++;
else
- term_beep(el);
+ terminal_beep(el);
break;
default:
@@ -297,7 +304,7 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.cursor != '\n') {
if (el->el_search.patlen >=
EL_BUFSIZ - LEN) {
- term_beep(el);
+ terminal_beep(el);
break;
}
el->el_search.patbuf[el->el_search.patlen++] =
@@ -310,14 +317,14 @@ ce_inc_search(EditLine *el, int dir)
re_refresh(el);
break;
} else if (isglob(*cp)) {
- term_beep(el);
+ terminal_beep(el);
break;
}
break;
default: /* Terminate and execute cmd */
endcmd[0] = ch;
- el_push(el, endcmd);
+ FUN(el,push)(el, endcmd);
/* FALLTHROUGH */
case 0033: /* ESC: Terminate */
@@ -379,9 +386,10 @@ ce_inc_search(EditLine *el, int dir)
/* avoid c_setpat */
el->el_state.lastcmd =
(el_action_t) newdir;
- ret = newdir == ED_SEARCH_PREV_HISTORY ?
+ ret = (el_action_t)
+ (newdir == ED_SEARCH_PREV_HISTORY ?
ed_search_prev_history(el, 0) :
- ed_search_next_history(el, 0);
+ ed_search_next_history(el, 0));
if (ret != CC_ERROR) {
el->el_line.cursor = newdir ==
ED_SEARCH_PREV_HISTORY ?
@@ -395,13 +403,13 @@ ce_inc_search(EditLine *el, int dir)
el->el_search.patbuf[el->el_search.patlen] =
'\0';
if (ret == CC_ERROR) {
- term_beep(el);
+ terminal_beep(el);
if (el->el_history.eventno !=
ohisteventno) {
el->el_history.eventno =
ohisteventno;
if (hist_get(el) == CC_ERROR)
- return (CC_ERROR);
+ return CC_ERROR;
}
el->el_line.cursor = ocursor;
pchar = '?';
@@ -426,14 +434,14 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_history.eventno != ohisteventno) {
el->el_history.eventno = ohisteventno;
if (hist_get(el) == CC_ERROR)
- return (CC_ERROR);
+ return CC_ERROR;
}
el->el_line.cursor = ocursor;
if (ret == CC_ERROR)
re_refresh(el);
}
if (done || ret != CC_NORM)
- return (ret);
+ return ret;
}
}
@@ -444,9 +452,9 @@ ce_inc_search(EditLine *el, int dir)
protected el_action_t
cv_search(EditLine *el, int dir)
{
- char ch;
- char tmpbuf[EL_BUFSIZ];
- int tmplen;
+ Char ch;
+ Char tmpbuf[EL_BUFSIZ];
+ ssize_t tmplen;
#ifdef ANCHOR
tmpbuf[0] = '.';
@@ -457,7 +465,7 @@ cv_search(EditLine *el, int dir)
el->el_search.patdir = dir;
tmplen = c_gets(el, &tmpbuf[LEN],
- dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" );
+ dir == ED_SEARCH_PREV_HISTORY ? STR("\n/") : STR("\n?") );
if (tmplen == -1)
return CC_REFRESH;
@@ -471,16 +479,16 @@ cv_search(EditLine *el, int dir)
*/
if (el->el_search.patlen == 0) {
re_refresh(el);
- return (CC_ERROR);
+ return CC_ERROR;
}
#ifdef ANCHOR
if (el->el_search.patbuf[0] != '.' &&
el->el_search.patbuf[0] != '*') {
- (void) strncpy(tmpbuf, el->el_search.patbuf,
- sizeof(tmpbuf) - 1);
+ (void) Strncpy(tmpbuf, el->el_search.patbuf,
+ sizeof(tmpbuf) / sizeof(*tmpbuf) - 1);
el->el_search.patbuf[0] = '.';
el->el_search.patbuf[1] = '*';
- (void) strncpy(&el->el_search.patbuf[2], tmpbuf,
+ (void) Strncpy(&el->el_search.patbuf[2], tmpbuf,
EL_BUFSIZ - 3);
el->el_search.patlen++;
el->el_search.patbuf[el->el_search.patlen++] = '.';
@@ -494,21 +502,21 @@ cv_search(EditLine *el, int dir)
tmpbuf[tmplen++] = '*';
#endif
tmpbuf[tmplen] = '\0';
- (void) strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
- el->el_search.patlen = tmplen;
+ (void) Strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
+ el->el_search.patlen = (size_t)tmplen;
}
el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */
el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) :
ed_search_next_history(el, 0)) == CC_ERROR) {
re_refresh(el);
- return (CC_ERROR);
+ return CC_ERROR;
}
if (ch == 0033) {
re_refresh(el);
return ed_newline(el, 0);
}
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -518,9 +526,9 @@ cv_search(EditLine *el, int dir)
protected el_action_t
ce_search_line(EditLine *el, int dir)
{
- char *cp = el->el_line.cursor;
- char *pattern = el->el_search.patbuf;
- char oc, *ocp;
+ Char *cp = el->el_line.cursor;
+ Char *pattern = el->el_search.patbuf;
+ Char oc, *ocp;
#ifdef ANCHOR
ocp = &pattern[1];
oc = *ocp;
@@ -535,21 +543,21 @@ ce_search_line(EditLine *el, int dir)
if (el_match(cp, ocp)) {
*ocp = oc;
el->el_line.cursor = cp;
- return (CC_NORM);
+ return CC_NORM;
}
}
*ocp = oc;
- return (CC_ERROR);
+ return CC_ERROR;
} else {
for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
if (el_match(cp, ocp)) {
*ocp = oc;
el->el_line.cursor = cp;
- return (CC_NORM);
+ return CC_NORM;
}
}
*ocp = oc;
- return (CC_ERROR);
+ return CC_ERROR;
}
}
@@ -558,12 +566,12 @@ ce_search_line(EditLine *el, int dir)
* Vi repeat search
*/
protected el_action_t
-cv_repeat_srch(EditLine *el, int c)
+cv_repeat_srch(EditLine *el, Int c)
{
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n",
- c, el->el_search.patlen, el->el_search.patbuf);
+ c, el->el_search.patlen, ct_encode_string(el->el_search.patbuf));
#endif
el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */
@@ -571,11 +579,11 @@ cv_repeat_srch(EditLine *el, int c)
switch (c) {
case ED_SEARCH_NEXT_HISTORY:
- return (ed_search_next_history(el, 0));
+ return ed_search_next_history(el, 0);
case ED_SEARCH_PREV_HISTORY:
- return (ed_search_prev_history(el, 0));
+ return ed_search_prev_history(el, 0);
default:
- return (CC_ERROR);
+ return CC_ERROR;
}
}
@@ -584,16 +592,16 @@ cv_repeat_srch(EditLine *el, int c)
* Vi character search
*/
protected el_action_t
-cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
+cv_csearch(EditLine *el, int direction, Int ch, int count, int tflag)
{
- char *cp;
+ Char *cp;
if (ch == 0)
return CC_ERROR;
- if (ch == -1) {
- char c;
- if (el_getc(el, &c) != 1)
+ if (ch == (Int)-1) {
+ Char c;
+ if (FUN(el,getc)(el, &c) != 1)
return ed_end_of_file(el, 0);
ch = c;
}
@@ -601,18 +609,18 @@ cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
/* Save for ';' and ',' commands */
el->el_search.chacha = ch;
el->el_search.chadir = direction;
- el->el_search.chatflg = tflag;
+ el->el_search.chatflg = (char)tflag;
cp = el->el_line.cursor;
while (count--) {
- if (*cp == ch)
+ if ((Int)*cp == ch)
cp += direction;
for (;;cp += direction) {
if (cp >= el->el_line.lastchar)
return CC_ERROR;
if (cp < el->el_line.buffer)
return CC_ERROR;
- if (*cp == ch)
+ if ((Int)*cp == ch)
break;
}
}
diff --git a/cmd-line-utils/libedit/search.h b/cmd-line-utils/libedit/search.h
index 2aa8f985013..d9f27e56185 100644
--- a/cmd-line-utils/libedit/search.h
+++ b/cmd-line-utils/libedit/search.h
@@ -1,4 +1,4 @@
-/* $NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $ */
+/* $NetBSD: search.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -43,24 +43,24 @@
#include "histedit.h"
typedef struct el_search_t {
- char *patbuf; /* The pattern buffer */
+ Char *patbuf; /* The pattern buffer */
size_t patlen; /* Length of the pattern buffer */
int patdir; /* Direction of the last search */
int chadir; /* Character search direction */
- char chacha; /* Character we are looking for */
+ Char chacha; /* Character we are looking for */
char chatflg; /* 0 if f, 1 if t */
} el_search_t;
-protected int el_match(const char *, const char *);
+protected int el_match(const Char *, const Char *);
protected int search_init(EditLine *);
protected void search_end(EditLine *);
-protected int c_hmatch(EditLine *, const char *);
+protected int c_hmatch(EditLine *, const Char *);
protected void c_setpat(EditLine *);
protected el_action_t ce_inc_search(EditLine *, int);
protected el_action_t cv_search(EditLine *, int);
protected el_action_t ce_search_line(EditLine *, int);
-protected el_action_t cv_repeat_srch(EditLine *, int);
-protected el_action_t cv_csearch(EditLine *, int, int, int, int);
+protected el_action_t cv_repeat_srch(EditLine *, Int);
+protected el_action_t cv_csearch(EditLine *, int, Int, int, int);
#endif /* _h_el_search */
diff --git a/cmd-line-utils/libedit/sig.c b/cmd-line-utils/libedit/sig.c
index 5307ee6ec60..986ad5792e2 100644
--- a/cmd-line-utils/libedit/sig.c
+++ b/cmd-line-utils/libedit/sig.c
@@ -1,4 +1,4 @@
-/* $NetBSD: sig.c,v 1.12 2008/09/10 15:45:37 christos Exp $ */
+/* $NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -57,15 +57,15 @@ private const int sighdl[] = {
- 1
};
-private void el_sig_handler(int);
+private void sig_handler(int);
-/* el_sig_handler():
+/* sig_handler():
* This is the handler called for all signals
* XXX: we cannot pass any data so we just store the old editline
* state in a private variable
*/
private void
-el_sig_handler(int signo)
+sig_handler(int signo)
{
int i;
sigset_t nset, oset;
@@ -74,12 +74,14 @@ el_sig_handler(int signo)
(void) sigaddset(&nset, signo);
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
+ sel->el_signal->sig_no = signo;
+
switch (signo) {
case SIGCONT:
tty_rawmode(sel);
if (ed_redisplay(sel, 0) == CC_REFRESH)
re_refresh(sel);
- term__flush(sel);
+ terminal__flush(sel);
break;
case SIGWINCH:
@@ -95,7 +97,10 @@ el_sig_handler(int signo)
if (signo == sighdl[i])
break;
- (void) signal(signo, sel->el_signal[i]);
+ (void) sigaction(signo, &sel->el_signal->sig_action[i], NULL);
+ sel->el_signal->sig_action[i].sa_handler = SIG_ERR;
+ sel->el_signal->sig_action[i].sa_flags = 0;
+ sigemptyset(&sel->el_signal->sig_action[i].sa_mask);
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
(void) kill(0, signo);
}
@@ -107,26 +112,29 @@ el_sig_handler(int signo)
protected int
sig_init(EditLine *el)
{
- int i;
- sigset_t nset, oset;
+ size_t i;
+ sigset_t *nset, oset;
- (void) sigemptyset(&nset);
-#define _DO(a) (void) sigaddset(&nset, a);
+ el->el_signal = el_malloc(sizeof(*el->el_signal));
+ if (el->el_signal == NULL)
+ return -1;
+
+ nset = &el->el_signal->sig_set;
+ (void) sigemptyset(nset);
+#define _DO(a) (void) sigaddset(nset, a);
ALLSIGS
#undef _DO
- (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+ (void) sigprocmask(SIG_BLOCK, nset, &oset);
-#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t))
-
- el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE);
- if (el->el_signal == NULL)
- return (-1);
- for (i = 0; sighdl[i] != -1; i++)
- el->el_signal[i] = SIG_ERR;
+ for (i = 0; sighdl[i] != -1; i++) {
+ el->el_signal->sig_action[i].sa_handler = SIG_ERR;
+ el->el_signal->sig_action[i].sa_flags = 0;
+ sigemptyset(&el->el_signal->sig_action[i].sa_mask);
+ }
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
- return (0);
+ return 0;
}
@@ -137,7 +145,7 @@ protected void
sig_end(EditLine *el)
{
- el_free((ptr_t) el->el_signal);
+ el_free(el->el_signal);
el->el_signal = NULL;
}
@@ -148,20 +156,21 @@ sig_end(EditLine *el)
protected void
sig_set(EditLine *el)
{
- int i;
- sigset_t nset, oset;
+ size_t i;
+ sigset_t oset;
+ struct sigaction osa, nsa;
- (void) sigemptyset(&nset);
-#define _DO(a) (void) sigaddset(&nset, a);
- ALLSIGS
-#undef _DO
- (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+ nsa.sa_handler = sig_handler;
+ nsa.sa_flags = 0;
+ sigemptyset(&nsa.sa_mask);
+
+ (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
for (i = 0; sighdl[i] != -1; i++) {
- el_signalhandler_t s;
/* This could happen if we get interrupted */
- if ((s = signal(sighdl[i], el_sig_handler)) != el_sig_handler)
- el->el_signal[i] = s;
+ if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
+ osa.sa_handler != sig_handler)
+ el->el_signal->sig_action[i] = osa;
}
sel = el;
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
@@ -174,20 +183,17 @@ sig_set(EditLine *el)
protected void
sig_clr(EditLine *el)
{
- int i;
- sigset_t nset, oset;
+ size_t i;
+ sigset_t oset;
- (void) sigemptyset(&nset);
-#define _DO(a) (void) sigaddset(&nset, a);
- ALLSIGS
-#undef _DO
- (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+ (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
for (i = 0; sighdl[i] != -1; i++)
- if (el->el_signal[i] != SIG_ERR)
- (void) signal(sighdl[i], el->el_signal[i]);
+ if (el->el_signal->sig_action[i].sa_handler != SIG_ERR)
+ (void)sigaction(sighdl[i],
+ &el->el_signal->sig_action[i], NULL);
sel = NULL; /* we are going to die if the handler is
* called */
- (void) sigprocmask(SIG_SETMASK, &oset, NULL);
+ (void)sigprocmask(SIG_SETMASK, &oset, NULL);
}
diff --git a/cmd-line-utils/libedit/sig.h b/cmd-line-utils/libedit/sig.h
index 2bd3c516d46..c957cfdf5a7 100644
--- a/cmd-line-utils/libedit/sig.h
+++ b/cmd-line-utils/libedit/sig.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sig.h,v 1.6 2008/07/12 15:27:14 christos Exp $ */
+/* $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -56,9 +56,13 @@
_DO(SIGTERM) \
_DO(SIGCONT) \
_DO(SIGWINCH)
+#define ALLSIGSNO 7
-typedef void (*el_signalhandler_t)(int);
-typedef el_signalhandler_t *el_signal_t;
+typedef struct {
+ struct sigaction sig_action[ALLSIGSNO];
+ sigset_t sig_set;
+ volatile sig_atomic_t sig_no;
+} *el_signal_t;
protected void sig_end(EditLine*);
protected int sig_init(EditLine*);
diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h
index a0369affbb0..33638d1565b 100644
--- a/cmd-line-utils/libedit/sys.h
+++ b/cmd-line-utils/libedit/sys.h
@@ -1,4 +1,4 @@
-/* $NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $ */
+/* $NetBSD: sys.h,v 1.17 2011/09/28 14:08:04 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -48,14 +48,6 @@
# define __attribute__(A)
#endif
-#ifndef _DIAGASSERT
-# define _DIAGASSERT(x)
-#endif
-
-#ifndef SIZE_T_MAX
-# define SIZE_T_MAX UINT_MAX
-#endif
-
#ifndef __BEGIN_DECLS
# ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
@@ -79,18 +71,8 @@
/* When we want to hide everything */
#endif
-#ifndef HAVE_U_INT32_T
-typedef unsigned int u_int32_t;
-#endif
-
-#ifndef _PTR_T
-# define _PTR_T
-typedef void *ptr_t;
-#endif
-
-#ifndef _IOCTL_T
-# define _IOCTL_T
-typedef void *ioctl_t;
+#ifndef __arraycount
+# define __arraycount(a) (sizeof(a) / sizeof(*(a)))
#endif
#include <stdio.h>
@@ -110,10 +92,44 @@ 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>
+
+#ifndef HAVE_WCSDUP
+wchar_t *wcsdup(const wchar_t *);
+#endif
+
+#ifndef _DIAGASSERT
+#define _DIAGASSERT(x)
+#endif
+
+#ifndef __RCSID
+#define __RCSID(x)
+#endif
+
+#ifndef HAVE_U_INT32_T
+typedef unsigned int u_int32_t;
+#endif
+
+#ifndef SIZE_T_MAX
+#define SIZE_T_MAX ((size_t)-1)
+#endif
+
#define REGEX /* Use POSIX.2 regular expression functions */
#undef REGEXP /* Use UNIX V8 regular expression functions */
-#ifdef __SunOS
+#if defined(__sun)
extern int tgetent(char *, const char *);
extern int tgetflag(char *);
extern int tgetnum(char *);
@@ -162,8 +178,8 @@ extern void perror(const char *);
# define strerror(e) sys_errlist[e]
# endif
# ifdef SABER
-extern ptr_t memcpy(ptr_t, const ptr_t, size_t);
-extern ptr_t memset(ptr_t, int, size_t);
+extern void * memcpy(void *, const void *, size_t);
+extern void * memset(void *, int, size_t);
# endif
extern char *fgetline(FILE *, int *);
#endif
diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/terminal.c
index 2f1aefa7117..fb5600a4140 100644
--- a/cmd-line-utils/libedit/term.c
+++ b/cmd-line-utils/libedit/terminal.c
@@ -1,4 +1,4 @@
-/* $NetBSD: term.c,v 1.48 2009/02/06 20:08:13 sketch Exp $ */
+/* $NetBSD: terminal.c,v 1.10 2011/10/04 15:27:04 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -41,15 +41,16 @@ static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
#endif /* not lint && not SCCSID */
/*
- * term.c: Editor/termcap-curses interface
- * We have to declare a static variable here, since the
- * termcap putchar routine does not take an argument!
+ * terminal.c: Editor/termcap-curses interface
+ * We have to declare a static variable here, since the
+ * termcap putchar routine does not take an argument!
*/
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
+#include <limits.h>
#if 0 /* TODO: do we need this */
#ifdef HAVE_TERMCAP_H
#include <termcap.h>
@@ -57,14 +58,15 @@ static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
#endif
#ifdef HAVE_CURSES_H
#include <curses.h>
-#endif
-#ifdef HAVE_NCURSES_H
+#elif HAVE_NCURSES_H
#include <ncurses.h>
#endif
-/* Don't use Solaris's term.h. */
-#if (defined(HAVE_TERM_H) && !defined(__SunOS))
+
+/* Solaris's term.h does horrid things. */
+#if defined(HAVE_TERM_H) && !defined(__sun)
#include <term.h>
#endif
+
#include <sys/types.h>
#include <sys/ioctl.h>
@@ -76,89 +78,17 @@ static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
/*
* IMPORTANT NOTE: these routines are allowed to look at the current screen
- * and the current possition assuming that it is correct. If this is not
+ * and the current position assuming that it is correct. If this is not
* true, then the update will be WRONG! This is (should be) a valid
* assumption...
*/
-#define TC_BUFSIZE 2048
-
-#define GoodStr(a) (el->el_term.t_str[a] != NULL && \
- el->el_term.t_str[a][0] != '\0')
-#define Str(a) el->el_term.t_str[a]
-#define Val(a) el->el_term.t_val[a]
+#define TC_BUFSIZE ((size_t)2048)
-#ifdef notdef
-private const struct {
- const char *b_name;
- int b_rate;
-} baud_rate[] = {
-#ifdef B0
- { "0", B0 },
-#endif
-#ifdef B50
- { "50", B50 },
-#endif
-#ifdef B75
- { "75", B75 },
-#endif
-#ifdef B110
- { "110", B110 },
-#endif
-#ifdef B134
- { "134", B134 },
-#endif
-#ifdef B150
- { "150", B150 },
-#endif
-#ifdef B200
- { "200", B200 },
-#endif
-#ifdef B300
- { "300", B300 },
-#endif
-#ifdef B600
- { "600", B600 },
-#endif
-#ifdef B900
- { "900", B900 },
-#endif
-#ifdef B1200
- { "1200", B1200 },
-#endif
-#ifdef B1800
- { "1800", B1800 },
-#endif
-#ifdef B2400
- { "2400", B2400 },
-#endif
-#ifdef B3600
- { "3600", B3600 },
-#endif
-#ifdef B4800
- { "4800", B4800 },
-#endif
-#ifdef B7200
- { "7200", B7200 },
-#endif
-#ifdef B9600
- { "9600", B9600 },
-#endif
-#ifdef EXTA
- { "19200", EXTA },
-#endif
-#ifdef B19200
- { "19200", B19200 },
-#endif
-#ifdef EXTB
- { "38400", EXTB },
-#endif
-#ifdef B38400
- { "38400", B38400 },
-#endif
- { NULL, 0 }
-};
-#endif
+#define GoodStr(a) (el->el_terminal.t_str[a] != NULL && \
+ el->el_terminal.t_str[a][0] != '\0')
+#define Str(a) el->el_terminal.t_str[a]
+#define Val(a) el->el_terminal.t_val[a]
private const struct termcapstr {
const char *name;
@@ -269,27 +199,28 @@ private const struct termcapval {
};
/* do two or more of the attributes use me */
-private void term_setflags(EditLine *);
-private int term_rebuffer_display(EditLine *);
-private void term_free_display(EditLine *);
-private int term_alloc_display(EditLine *);
-private void term_alloc(EditLine *, const struct termcapstr *, const char *);
-private void term_init_arrow(EditLine *);
-private void term_reset_arrow(EditLine *);
-private int term_putc(int);
-private void term_tputs(EditLine *, const char *, int);
+private void terminal_setflags(EditLine *);
+private int terminal_rebuffer_display(EditLine *);
+private void terminal_free_display(EditLine *);
+private int terminal_alloc_display(EditLine *);
+private void terminal_alloc(EditLine *, const struct termcapstr *,
+ const char *);
+private void terminal_init_arrow(EditLine *);
+private void terminal_reset_arrow(EditLine *);
+private int terminal_putc(int);
+private void terminal_tputs(EditLine *, const char *, int);
#ifdef _REENTRANT
-private pthread_mutex_t term_mutex = PTHREAD_MUTEX_INITIALIZER;
+private pthread_mutex_t terminal_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
-private FILE *term_outfile = NULL;
+private FILE *terminal_outfile = NULL;
-/* term_setflags():
+/* terminal_setflags():
* Set the terminal capability flags
*/
private void
-term_setflags(EditLine *el)
+terminal_setflags(EditLine *el)
{
EL_FLAGS = 0;
if (el->el_tty.t_tabs)
@@ -330,67 +261,74 @@ term_setflags(EditLine *el)
#endif /* DEBUG_SCREEN */
}
-/* term_init():
+/* terminal_init():
* Initialize the terminal stuff
*/
protected int
-term_init(EditLine *el)
+terminal_init(EditLine *el)
{
- el->el_term.t_buf = (char *) el_malloc(TC_BUFSIZE);
- if (el->el_term.t_buf == NULL)
- return (-1);
- el->el_term.t_cap = (char *) el_malloc(TC_BUFSIZE);
- if (el->el_term.t_cap == NULL)
- return (-1);
- el->el_term.t_fkey = (fkey_t *) el_malloc(A_K_NKEYS * sizeof(fkey_t));
- if (el->el_term.t_fkey == NULL)
- return (-1);
- el->el_term.t_loc = 0;
- el->el_term.t_str = (char **) el_malloc(T_str * sizeof(char *));
- if (el->el_term.t_str == NULL)
- return (-1);
- (void) memset(el->el_term.t_str, 0, T_str * sizeof(char *));
- el->el_term.t_val = (int *) el_malloc(T_val * sizeof(int));
- if (el->el_term.t_val == NULL)
- return (-1);
- (void) memset(el->el_term.t_val, 0, T_val * sizeof(int));
- (void) term_set(el, NULL);
- term_init_arrow(el);
- return (0);
+ el->el_terminal.t_buf = el_malloc(TC_BUFSIZE *
+ sizeof(*el->el_terminal.t_buf));
+ if (el->el_terminal.t_buf == NULL)
+ return -1;
+ el->el_terminal.t_cap = el_malloc(TC_BUFSIZE *
+ sizeof(*el->el_terminal.t_cap));
+ if (el->el_terminal.t_cap == NULL)
+ return -1;
+ el->el_terminal.t_fkey = el_malloc(A_K_NKEYS *
+ sizeof(*el->el_terminal.t_fkey));
+ if (el->el_terminal.t_fkey == NULL)
+ return -1;
+ el->el_terminal.t_loc = 0;
+ el->el_terminal.t_str = el_malloc(T_str *
+ sizeof(*el->el_terminal.t_str));
+ if (el->el_terminal.t_str == NULL)
+ return -1;
+ (void) memset(el->el_terminal.t_str, 0, T_str *
+ sizeof(*el->el_terminal.t_str));
+ el->el_terminal.t_val = el_malloc(T_val *
+ sizeof(*el->el_terminal.t_val));
+ if (el->el_terminal.t_val == NULL)
+ return -1;
+ (void) memset(el->el_terminal.t_val, 0, T_val *
+ sizeof(*el->el_terminal.t_val));
+ (void) terminal_set(el, NULL);
+ terminal_init_arrow(el);
+ return 0;
}
-/* term_end():
+/* terminal_end():
* Clean up the terminal stuff
*/
protected void
-term_end(EditLine *el)
+terminal_end(EditLine *el)
{
- el_free((ptr_t) el->el_term.t_buf);
- el->el_term.t_buf = NULL;
- el_free((ptr_t) el->el_term.t_cap);
- el->el_term.t_cap = NULL;
- el->el_term.t_loc = 0;
- el_free((ptr_t) el->el_term.t_str);
- el->el_term.t_str = NULL;
- el_free((ptr_t) el->el_term.t_val);
- el->el_term.t_val = NULL;
- el_free((ptr_t) el->el_term.t_fkey);
- el->el_term.t_fkey = NULL;
- term_free_display(el);
+ el_free(el->el_terminal.t_buf);
+ el->el_terminal.t_buf = NULL;
+ el_free(el->el_terminal.t_cap);
+ el->el_terminal.t_cap = NULL;
+ el->el_terminal.t_loc = 0;
+ el_free(el->el_terminal.t_str);
+ el->el_terminal.t_str = NULL;
+ el_free(el->el_terminal.t_val);
+ el->el_terminal.t_val = NULL;
+ el_free(el->el_terminal.t_fkey);
+ el->el_terminal.t_fkey = NULL;
+ terminal_free_display(el);
}
-/* term_alloc():
+/* terminal_alloc():
* Maintain a string pool for termcap strings
*/
private void
-term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
+terminal_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
{
char termbuf[TC_BUFSIZE];
- int tlen, clen;
- char **tlist = el->el_term.t_str;
+ size_t tlen, clen;
+ char **tlist = el->el_terminal.t_str;
char **tmp, **str = &tlist[t - tstr];
if (cap == NULL || *cap == '\0') {
@@ -412,11 +350,11 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
/*
* New string is longer; see if we have enough space to append
*/
- if (el->el_term.t_loc + 3 < TC_BUFSIZE) {
+ if (el->el_terminal.t_loc + 3 < TC_BUFSIZE) {
/* XXX strcpy is safe */
- (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc],
- cap);
- el->el_term.t_loc += clen + 1; /* one for \0 */
+ (void) strcpy(*str = &el->el_terminal.t_buf[
+ el->el_terminal.t_loc], cap);
+ el->el_terminal.t_loc += clen + 1; /* one for \0 */
return;
}
/*
@@ -432,124 +370,126 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
continue;
termbuf[tlen++] = '\0';
}
- memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE);
- el->el_term.t_loc = tlen;
- if (el->el_term.t_loc + 3 >= TC_BUFSIZE) {
+ memcpy(el->el_terminal.t_buf, termbuf, TC_BUFSIZE);
+ el->el_terminal.t_loc = tlen;
+ if (el->el_terminal.t_loc + 3 >= TC_BUFSIZE) {
(void) fprintf(el->el_errfile,
"Out of termcap string space.\n");
return;
}
/* XXX strcpy is safe */
- (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap);
- el->el_term.t_loc += clen + 1; /* one for \0 */
+ (void) strcpy(*str = &el->el_terminal.t_buf[el->el_terminal.t_loc],
+ cap);
+ el->el_terminal.t_loc += (size_t)clen + 1; /* one for \0 */
return;
}
-/* term_rebuffer_display():
+/* terminal_rebuffer_display():
* Rebuffer the display after the screen changed size
*/
private int
-term_rebuffer_display(EditLine *el)
+terminal_rebuffer_display(EditLine *el)
{
- coord_t *c = &el->el_term.t_size;
+ coord_t *c = &el->el_terminal.t_size;
- term_free_display(el);
+ terminal_free_display(el);
c->h = Val(T_co);
c->v = Val(T_li);
- if (term_alloc_display(el) == -1)
- return (-1);
- return (0);
+ if (terminal_alloc_display(el) == -1)
+ return -1;
+ return 0;
}
-/* term_alloc_display():
+/* terminal_alloc_display():
* Allocate a new display.
*/
private int
-term_alloc_display(EditLine *el)
+terminal_alloc_display(EditLine *el)
{
int i;
- char **b;
- coord_t *c = &el->el_term.t_size;
+ Char **b;
+ coord_t *c = &el->el_terminal.t_size;
- b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1)));
+ b = el_malloc(sizeof(*b) * (size_t)(c->v + 1));
if (b == NULL)
- return (-1);
+ return -1;
for (i = 0; i < c->v; i++) {
- b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
+ b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
if (b[i] == NULL) {
while (--i >= 0)
- el_free((ptr_t) b[i]);
- el_free((ptr_t) b);
- return (-1);
+ el_free(b[i]);
+ el_free(b);
+ return -1;
}
}
b[c->v] = NULL;
el->el_display = b;
- b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1)));
+ b = el_malloc(sizeof(*b) * (size_t)(c->v + 1));
if (b == NULL)
- return (-1);
+ return -1;
for (i = 0; i < c->v; i++) {
- b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
+ b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
if (b[i] == NULL) {
while (--i >= 0)
- el_free((ptr_t) b[i]);
- el_free((ptr_t) b);
- return (-1);
+ el_free(b[i]);
+ el_free(b);
+ return -1;
}
}
b[c->v] = NULL;
el->el_vdisplay = b;
- return (0);
+ return 0;
}
-/* term_free_display():
+/* terminal_free_display():
* Free the display buffers
*/
private void
-term_free_display(EditLine *el)
+terminal_free_display(EditLine *el)
{
- char **b;
- char **bufp;
+ Char **b;
+ Char **bufp;
b = el->el_display;
el->el_display = NULL;
if (b != NULL) {
for (bufp = b; *bufp != NULL; bufp++)
- el_free((ptr_t) * bufp);
- el_free((ptr_t) b);
+ el_free(*bufp);
+ el_free(b);
}
b = el->el_vdisplay;
el->el_vdisplay = NULL;
if (b != NULL) {
for (bufp = b; *bufp != NULL; bufp++)
- el_free((ptr_t) * bufp);
- el_free((ptr_t) b);
+ el_free(*bufp);
+ el_free(b);
}
}
-/* term_move_to_line():
+/* terminal_move_to_line():
* move to line <where> (first line == 0)
* as efficiently as possible
*/
protected void
-term_move_to_line(EditLine *el, int where)
+terminal_move_to_line(EditLine *el, int where)
{
int del;
if (where == el->el_cursor.v)
return;
- if (where > el->el_term.t_size.v) {
+ if (where > el->el_terminal.t_size.v) {
#ifdef DEBUG_SCREEN
(void) fprintf(el->el_errfile,
- "term_move_to_line: where is ridiculous: %d\r\n", where);
+ "terminal_move_to_line: where is ridiculous: %d\r\n",
+ where);
#endif /* DEBUG_SCREEN */
return;
}
@@ -557,21 +497,31 @@ term_move_to_line(EditLine *el, int where)
while (del > 0) {
if (EL_HAS_AUTO_MARGINS &&
el->el_display[el->el_cursor.v][0] != '\0') {
+ size_t h = (size_t)
+ (el->el_terminal.t_size.h - 1);
+#ifdef WIDECHAR
+ for (; h > 0 &&
+ el->el_display[el->el_cursor.v][h] ==
+ MB_FILL_CHAR;
+ h--)
+ continue;
+#endif
/* move without newline */
- term_move_to_char(el, el->el_term.t_size.h - 1);
- term_overwrite(el,
- &el->el_display[el->el_cursor.v][el->el_cursor.h],
- 1);
+ terminal_move_to_char(el, (int)h);
+ terminal_overwrite(el, &el->el_display
+ [el->el_cursor.v][el->el_cursor.h],
+ (size_t)(el->el_terminal.t_size.h -
+ el->el_cursor.h));
/* updates Cursor */
del--;
} else {
if ((del > 1) && GoodStr(T_DO)) {
- term_tputs(el, tgoto(Str(T_DO), del,
+ terminal_tputs(el, tgoto(Str(T_DO), del,
del), del);
del = 0;
} else {
for (; del > 0; del--)
- term__putc(el, '\n');
+ terminal__putc(el, '\n');
/* because the \n will become \r\n */
el->el_cursor.h = 0;
}
@@ -579,22 +529,22 @@ term_move_to_line(EditLine *el, int where)
}
} else { /* del < 0 */
if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
- term_tputs(el, tgoto(Str(T_UP), -del, -del), -del);
+ terminal_tputs(el, tgoto(Str(T_UP), -del, -del), -del);
else {
if (GoodStr(T_up))
for (; del < 0; del++)
- term_tputs(el, Str(T_up), 1);
+ terminal_tputs(el, Str(T_up), 1);
}
}
el->el_cursor.v = where;/* now where is here */
}
-/* term_move_to_char():
+/* terminal_move_to_char():
* Move to the character position specified
*/
protected void
-term_move_to_char(EditLine *el, int where)
+terminal_move_to_char(EditLine *el, int where)
{
int del, i;
@@ -602,15 +552,16 @@ mc_again:
if (where == el->el_cursor.h)
return;
- if (where > el->el_term.t_size.h) {
+ if (where > el->el_terminal.t_size.h) {
#ifdef DEBUG_SCREEN
(void) fprintf(el->el_errfile,
- "term_move_to_char: where is riduculous: %d\r\n", where);
+ "terminal_move_to_char: where is riduculous: %d\r\n",
+ where);
#endif /* DEBUG_SCREEN */
return;
}
if (!where) { /* if where is first column */
- term__putc(el, '\r'); /* do a CR */
+ terminal__putc(el, '\r'); /* do a CR */
el->el_cursor.h = 0;
return;
}
@@ -618,24 +569,32 @@ mc_again:
if ((del < -4 || del > 4) && GoodStr(T_ch))
/* go there directly */
- term_tputs(el, tgoto(Str(T_ch), where, where), where);
+ terminal_tputs(el, tgoto(Str(T_ch), where, where), where);
else {
if (del > 0) { /* moving forward */
if ((del > 4) && GoodStr(T_RI))
- term_tputs(el, tgoto(Str(T_RI), del, del), del);
+ terminal_tputs(el, tgoto(Str(T_RI), del, del),
+ del);
else {
/* if I can do tabs, use them */
if (EL_CAN_TAB) {
if ((el->el_cursor.h & 0370) !=
- (where & 0370)) {
+ (where & ~0x7)
+#ifdef WIDECHAR
+ && (el->el_display[
+ el->el_cursor.v][where & 0370] !=
+ MB_FILL_CHAR)
+#endif
+ ) {
/* if not within tab stop */
for (i =
(el->el_cursor.h & 0370);
- i < (where & 0370);
+ i < (where & ~0x7);
i += 8)
- term__putc(el, '\t');
+ terminal__putc(el,
+ '\t');
/* then tab over */
- el->el_cursor.h = where & 0370;
+ el->el_cursor.h = where & ~0x7;
}
}
/*
@@ -643,17 +602,17 @@ mc_again:
* chars, so we do.
*/
/*
- * NOTE THAT term_overwrite() WILL CHANGE
+ * NOTE THAT terminal_overwrite() WILL CHANGE
* el->el_cursor.h!!!
*/
- term_overwrite(el,
- &el->el_display[el->el_cursor.v][el->el_cursor.h],
- where - el->el_cursor.h);
+ terminal_overwrite(el, &el->el_display[
+ el->el_cursor.v][el->el_cursor.h],
+ (size_t)(where - el->el_cursor.h));
}
} else { /* del < 0 := moving backward */
if ((-del > 4) && GoodStr(T_LE))
- term_tputs(el, tgoto(Str(T_LE), -del, -del),
+ terminal_tputs(el, tgoto(Str(T_LE), -del, -del),
-del);
else { /* can't go directly there */
/*
@@ -665,12 +624,12 @@ mc_again:
(((unsigned int) where >> 3) +
(where & 07)))
: (-del > where)) {
- term__putc(el, '\r'); /* do a CR */
+ terminal__putc(el, '\r');/* do a CR */
el->el_cursor.h = 0;
goto mc_again; /* and try again */
}
for (i = 0; i < -del; i++)
- term__putc(el, '\b');
+ terminal__putc(el, '\b');
}
}
}
@@ -678,53 +637,72 @@ mc_again:
}
-/* term_overwrite():
+/* terminal_overwrite():
* Overstrike num characters
+ * Assumes MB_FILL_CHARs are present to keep the column count correct
*/
protected void
-term_overwrite(EditLine *el, const char *cp, int n)
+terminal_overwrite(EditLine *el, const Char *cp, size_t n)
{
- if (n <= 0)
- return; /* catch bugs */
+#ifdef WIDECHAR
+ int width;
+#endif
- if (n > el->el_term.t_size.h) {
+ if (n == 0)
+ return;
+
+ if (n > (size_t)el->el_terminal.t_size.h) {
#ifdef DEBUG_SCREEN
(void) fprintf(el->el_errfile,
- "term_overwrite: n is riduculous: %d\r\n", n);
+ "terminal_overwrite: n is riduculous: %d\r\n", n);
#endif /* DEBUG_SCREEN */
return;
}
- do {
- term__putc(el, *cp++);
- el->el_cursor.h++;
- } while (--n);
- if (el->el_cursor.h >= el->el_term.t_size.h) { /* wrap? */
+ do {
+#ifdef WIDECHAR
+ width = wcwidth(*cp); /* Returns -1 for faux character. */
+ if (width != -1)
+ el->el_cursor.h += width;
+#else
+ el->el_cursor.h++;
+#endif
+ /* terminal__putc() ignores any MB_FILL_CHARs */
+ terminal__putc(el, *cp++);
+ } while (--n);
+
+ if (el->el_cursor.h >= el->el_terminal.t_size.h) { /* wrap? */
if (EL_HAS_AUTO_MARGINS) { /* yes */
el->el_cursor.h = 0;
el->el_cursor.v++;
if (EL_HAS_MAGIC_MARGINS) {
/* force the wrap to avoid the "magic"
* situation */
- char c;
- if ((c = el->el_display[el->el_cursor.v][el->el_cursor.h])
- != '\0')
- term_overwrite(el, &c, 1);
- else
- term__putc(el, ' ');
- el->el_cursor.h = 1;
+ Char c;
+ if ((c = el->el_display[el->el_cursor.v]
+ [el->el_cursor.h]) != '\0') {
+ terminal_overwrite(el, &c, (size_t)1);
+#ifdef WIDECHAR
+ while (el->el_display[el->el_cursor.v]
+ [el->el_cursor.h] == MB_FILL_CHAR)
+ el->el_cursor.h++;
+#endif
+ } else {
+ terminal__putc(el, ' ');
+ el->el_cursor.h = 1;
+ }
}
} else /* no wrap, but cursor stays on screen */
- el->el_cursor.h = el->el_term.t_size.h;
+ el->el_cursor.h = el->el_terminal.t_size.h - 1;
}
}
-/* term_deletechars():
+/* terminal_deletechars():
* Delete num characters
*/
protected void
-term_deletechars(EditLine *el, int num)
+terminal_deletechars(EditLine *el, int num)
{
if (num <= 0)
return;
@@ -735,37 +713,38 @@ term_deletechars(EditLine *el, int num)
#endif /* DEBUG_EDIT */
return;
}
- if (num > el->el_term.t_size.h) {
+ if (num > el->el_terminal.t_size.h) {
#ifdef DEBUG_SCREEN
(void) fprintf(el->el_errfile,
- "term_deletechars: num is riduculous: %d\r\n", num);
+ "terminal_deletechars: num is riduculous: %d\r\n", num);
#endif /* DEBUG_SCREEN */
return;
}
if (GoodStr(T_DC)) /* if I have multiple delete */
if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more
* expen. */
- term_tputs(el, tgoto(Str(T_DC), num, num), num);
+ terminal_tputs(el, tgoto(Str(T_DC), num, num), num);
return;
}
if (GoodStr(T_dm)) /* if I have delete mode */
- term_tputs(el, Str(T_dm), 1);
+ terminal_tputs(el, Str(T_dm), 1);
if (GoodStr(T_dc)) /* else do one at a time */
while (num--)
- term_tputs(el, Str(T_dc), 1);
+ terminal_tputs(el, Str(T_dc), 1);
if (GoodStr(T_ed)) /* if I have delete mode */
- term_tputs(el, Str(T_ed), 1);
+ terminal_tputs(el, Str(T_ed), 1);
}
-/* term_insertwrite():
+/* terminal_insertwrite():
* Puts terminal in insert character mode or inserts num
* characters in the line
+ * Assumes MB_FILL_CHARs are present to keep column count correct
*/
protected void
-term_insertwrite(EditLine *el, char *cp, int num)
+terminal_insertwrite(EditLine *el, Char *cp, int num)
{
if (num <= 0)
return;
@@ -775,7 +754,7 @@ term_insertwrite(EditLine *el, char *cp, int num)
#endif /* DEBUG_EDIT */
return;
}
- if (num > el->el_term.t_size.h) {
+ if (num > el->el_terminal.t_size.h) {
#ifdef DEBUG_SCREEN
(void) fprintf(el->el_errfile,
"StartInsert: num is riduculous: %d\r\n", num);
@@ -785,120 +764,106 @@ term_insertwrite(EditLine *el, char *cp, int num)
if (GoodStr(T_IC)) /* if I have multiple insert */
if ((num > 1) || !GoodStr(T_ic)) {
/* if ic would be more expensive */
- term_tputs(el, tgoto(Str(T_IC), num, num), num);
- term_overwrite(el, cp, num);
+ terminal_tputs(el, tgoto(Str(T_IC), num, num), num);
+ terminal_overwrite(el, cp, (size_t)num);
/* this updates el_cursor.h */
return;
}
if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */
- term_tputs(el, Str(T_im), 1);
+ terminal_tputs(el, Str(T_im), 1);
el->el_cursor.h += num;
do
- term__putc(el, *cp++);
+ terminal__putc(el, *cp++);
while (--num);
if (GoodStr(T_ip)) /* have to make num chars insert */
- term_tputs(el, Str(T_ip), 1);
+ terminal_tputs(el, Str(T_ip), 1);
- term_tputs(el, Str(T_ei), 1);
+ terminal_tputs(el, Str(T_ei), 1);
return;
}
do {
if (GoodStr(T_ic)) /* have to make num chars insert */
- term_tputs(el, Str(T_ic), 1);
+ terminal_tputs(el, Str(T_ic), 1);
- term__putc(el, *cp++);
+ terminal__putc(el, *cp++);
el->el_cursor.h++;
if (GoodStr(T_ip)) /* have to make num chars insert */
- term_tputs(el, Str(T_ip), 1);
+ terminal_tputs(el, Str(T_ip), 1);
/* pad the inserted char */
} while (--num);
}
-/* term_clear_EOL():
+/* terminal_clear_EOL():
* clear to end of line. There are num characters to clear
*/
protected void
-term_clear_EOL(EditLine *el, int num)
+terminal_clear_EOL(EditLine *el, int num)
{
int i;
if (EL_CAN_CEOL && GoodStr(T_ce))
- term_tputs(el, Str(T_ce), 1);
+ terminal_tputs(el, Str(T_ce), 1);
else {
for (i = 0; i < num; i++)
- term__putc(el, ' ');
+ terminal__putc(el, ' ');
el->el_cursor.h += num; /* have written num spaces */
}
}
-/* term_clear_screen():
+/* terminal_clear_screen():
* Clear the screen
*/
protected void
-term_clear_screen(EditLine *el)
+terminal_clear_screen(EditLine *el)
{ /* clear the whole screen and home */
if (GoodStr(T_cl))
/* send the clear screen code */
- term_tputs(el, Str(T_cl), Val(T_li));
+ terminal_tputs(el, Str(T_cl), Val(T_li));
else if (GoodStr(T_ho) && GoodStr(T_cd)) {
- term_tputs(el, Str(T_ho), Val(T_li)); /* home */
+ terminal_tputs(el, Str(T_ho), Val(T_li)); /* home */
/* clear to bottom of screen */
- term_tputs(el, Str(T_cd), Val(T_li));
+ terminal_tputs(el, Str(T_cd), Val(T_li));
} else {
- term__putc(el, '\r');
- term__putc(el, '\n');
+ terminal__putc(el, '\r');
+ terminal__putc(el, '\n');
}
}
-/* term_beep():
+/* terminal_beep():
* Beep the way the terminal wants us
*/
protected void
-term_beep(EditLine *el)
+terminal_beep(EditLine *el)
{
if (GoodStr(T_bl))
/* what termcap says we should use */
- term_tputs(el, Str(T_bl), 1);
+ terminal_tputs(el, Str(T_bl), 1);
else
- term__putc(el, '\007'); /* an ASCII bell; ^G */
+ terminal__putc(el, '\007'); /* an ASCII bell; ^G */
}
-#ifdef notdef
-/* term_clear_to_bottom():
- * Clear to the bottom of the screen
- */
-protected void
-term_clear_to_bottom(EditLine *el)
-{
- if (GoodStr(T_cd))
- term_tputs(el, Str(T_cd), Val(T_li));
- else if (GoodStr(T_ce))
- term_tputs(el, Str(T_ce), Val(T_li));
-}
-#endif
-
protected void
-term_get(EditLine *el, const char **term)
+terminal_get(EditLine *el, const char **term)
{
- *term = el->el_term.t_name;
+ *term = el->el_terminal.t_name;
}
-/* term_set():
+/* terminal_set():
* Read in the terminal capabilities from the requested terminal
*/
protected int
-term_set(EditLine *el, const char *term)
+terminal_set(EditLine *el, const char *term)
{
int i;
char buf[TC_BUFSIZE];
@@ -923,9 +888,9 @@ term_set(EditLine *el, const char *term)
if (strcmp(term, "emacs") == 0)
el->el_flags |= EDIT_DISABLED;
- memset(el->el_term.t_cap, 0, TC_BUFSIZE);
+ memset(el->el_terminal.t_cap, 0, TC_BUFSIZE);
- i = tgetent(el->el_term.t_cap, term);
+ i = tgetent(el->el_terminal.t_cap, term);
if (i <= 0) {
if (i == -1)
@@ -940,23 +905,23 @@ term_set(EditLine *el, const char *term)
Val(T_pt) = Val(T_km) = Val(T_li) = 0;
Val(T_xt) = Val(T_MT);
for (t = tstr; t->name != NULL; t++)
- term_alloc(el, t, NULL);
+ terminal_alloc(el, t, NULL);
} else {
/* auto/magic margins */
- Val(T_am) = tgetflag("am");
- Val(T_xn) = tgetflag("xn");
+ Val(T_am) = tgetflag((char*) "am");
+ Val(T_xn) = tgetflag((char*) "xn");
/* Can we tab */
- Val(T_pt) = tgetflag("pt");
- Val(T_xt) = tgetflag("xt");
+ Val(T_pt) = tgetflag((char*) "pt");
+ Val(T_xt) = tgetflag((char*) "xt");
/* do we have a meta? */
- Val(T_km) = tgetflag("km");
- Val(T_MT) = tgetflag("MT");
+ Val(T_km) = tgetflag((char*) "km");
+ Val(T_MT) = tgetflag((char*) "MT");
/* Get the size */
- Val(T_co) = tgetnum("co");
- Val(T_li) = tgetnum("li");
+ Val(T_co) = tgetnum((char*) "co");
+ Val(T_li) = tgetnum((char*) "li");
for (t = tstr; t->name != NULL; t++) {
/* XXX: some systems' tgetstr needs non const */
- term_alloc(el, t, tgetstr(strchr(t->name, *t->name),
+ terminal_alloc(el, t, tgetstr(strchr(t->name, *t->name),
&area));
}
}
@@ -966,28 +931,28 @@ term_set(EditLine *el, const char *term)
if (Val(T_li) < 1)
Val(T_li) = 24;
- el->el_term.t_size.v = Val(T_co);
- el->el_term.t_size.h = Val(T_li);
+ el->el_terminal.t_size.v = Val(T_co);
+ el->el_terminal.t_size.h = Val(T_li);
- term_setflags(el);
+ terminal_setflags(el);
/* get the correct window size */
- (void) term_get_size(el, &lins, &cols);
- if (term_change_size(el, lins, cols) == -1)
- return (-1);
+ (void) terminal_get_size(el, &lins, &cols);
+ if (terminal_change_size(el, lins, cols) == -1)
+ return -1;
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
- term_bind_arrow(el);
- el->el_term.t_name = term;
- return (i <= 0 ? -1 : 0);
+ terminal_bind_arrow(el);
+ el->el_terminal.t_name = term;
+ return i <= 0 ? -1 : 0;
}
-/* term_get_size():
+/* terminal_get_size():
* Return the new window size in lines and cols, and
* true if the size was changed.
*/
protected int
-term_get_size(EditLine *el, int *lins, int *cols)
+terminal_get_size(EditLine *el, int *lins, int *cols)
{
*cols = Val(T_co);
@@ -996,7 +961,7 @@ term_get_size(EditLine *el, int *lins, int *cols)
#ifdef TIOCGWINSZ
{
struct winsize ws;
- if (ioctl(el->el_infd, TIOCGWINSZ, (ioctl_t) & ws) != -1) {
+ if (ioctl(el->el_infd, TIOCGWINSZ, &ws) != -1) {
if (ws.ws_col)
*cols = ws.ws_col;
if (ws.ws_row)
@@ -1007,7 +972,7 @@ term_get_size(EditLine *el, int *lins, int *cols)
#ifdef TIOCGSIZE
{
struct ttysize ts;
- if (ioctl(el->el_infd, TIOCGSIZE, (ioctl_t) & ts) != -1) {
+ if (ioctl(el->el_infd, TIOCGSIZE, &ts) != -1) {
if (ts.ts_cols)
*cols = ts.ts_cols;
if (ts.ts_lines)
@@ -1015,15 +980,15 @@ term_get_size(EditLine *el, int *lins, int *cols)
}
}
#endif
- return (Val(T_co) != *cols || Val(T_li) != *lins);
+ return Val(T_co) != *cols || Val(T_li) != *lins;
}
-/* term_change_size():
+/* terminal_change_size():
* Change the size of the terminal
*/
protected int
-term_change_size(EditLine *el, int lins, int cols)
+terminal_change_size(EditLine *el, int lins, int cols)
{
/*
* Just in case
@@ -1032,283 +997,301 @@ term_change_size(EditLine *el, int lins, int cols)
Val(T_li) = (lins < 1) ? 24 : lins;
/* re-make display buffers */
- if (term_rebuffer_display(el) == -1)
- return (-1);
+ if (terminal_rebuffer_display(el) == -1)
+ return -1;
re_clear_display(el);
- return (0);
+ return 0;
}
-/* term_init_arrow():
+/* terminal_init_arrow():
* Initialize the arrow key bindings from termcap
*/
private void
-term_init_arrow(EditLine *el)
+terminal_init_arrow(EditLine *el)
{
- fkey_t *arrow = el->el_term.t_fkey;
+ funckey_t *arrow = el->el_terminal.t_fkey;
- arrow[A_K_DN].name = "down";
+ arrow[A_K_DN].name = STR("down");
arrow[A_K_DN].key = T_kd;
arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY;
arrow[A_K_DN].type = XK_CMD;
- arrow[A_K_UP].name = "up";
+ arrow[A_K_UP].name = STR("up");
arrow[A_K_UP].key = T_ku;
arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY;
arrow[A_K_UP].type = XK_CMD;
- arrow[A_K_LT].name = "left";
+ arrow[A_K_LT].name = STR("left");
arrow[A_K_LT].key = T_kl;
arrow[A_K_LT].fun.cmd = ED_PREV_CHAR;
arrow[A_K_LT].type = XK_CMD;
- arrow[A_K_RT].name = "right";
+ arrow[A_K_RT].name = STR("right");
arrow[A_K_RT].key = T_kr;
arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR;
arrow[A_K_RT].type = XK_CMD;
- arrow[A_K_HO].name = "home";
+ arrow[A_K_HO].name = STR("home");
arrow[A_K_HO].key = T_kh;
arrow[A_K_HO].fun.cmd = ED_MOVE_TO_BEG;
arrow[A_K_HO].type = XK_CMD;
- arrow[A_K_EN].name = "end";
+ arrow[A_K_EN].name = STR("end");
arrow[A_K_EN].key = T_at7;
arrow[A_K_EN].fun.cmd = ED_MOVE_TO_END;
arrow[A_K_EN].type = XK_CMD;
}
-/* term_reset_arrow():
+/* terminal_reset_arrow():
* Reset arrow key bindings
*/
private void
-term_reset_arrow(EditLine *el)
+terminal_reset_arrow(EditLine *el)
{
- fkey_t *arrow = el->el_term.t_fkey;
- static const char strA[] = {033, '[', 'A', '\0'};
- static const char strB[] = {033, '[', 'B', '\0'};
- static const char strC[] = {033, '[', 'C', '\0'};
- static const char strD[] = {033, '[', 'D', '\0'};
- static const char strH[] = {033, '[', 'H', '\0'};
- static const char strF[] = {033, '[', 'F', '\0'};
- static const char stOA[] = {033, 'O', 'A', '\0'};
- static const char stOB[] = {033, 'O', 'B', '\0'};
- static const char stOC[] = {033, 'O', 'C', '\0'};
- static const char stOD[] = {033, 'O', 'D', '\0'};
- static const char stOH[] = {033, 'O', 'H', '\0'};
- static const char stOF[] = {033, 'O', 'F', '\0'};
-
- key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
- key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
-
- if (el->el_map.type == MAP_VI) {
- key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
- key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
- key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
- key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
- key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
- key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
- key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
- }
+ funckey_t *arrow = el->el_terminal.t_fkey;
+ static const Char strA[] = {033, '[', 'A', '\0'};
+ static const Char strB[] = {033, '[', 'B', '\0'};
+ static const Char strC[] = {033, '[', 'C', '\0'};
+ static const Char strD[] = {033, '[', 'D', '\0'};
+ static const Char strH[] = {033, '[', 'H', '\0'};
+ static const Char strF[] = {033, '[', 'F', '\0'};
+ static const Char stOA[] = {033, 'O', 'A', '\0'};
+ static const Char stOB[] = {033, 'O', 'B', '\0'};
+ static const Char stOC[] = {033, 'O', 'C', '\0'};
+ static const Char stOD[] = {033, 'O', 'D', '\0'};
+ static const Char stOH[] = {033, 'O', 'H', '\0'};
+ static const Char stOF[] = {033, 'O', 'F', '\0'};
+
+ keymacro_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ keymacro_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ keymacro_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ keymacro_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ keymacro_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+ keymacro_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+ keymacro_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ keymacro_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ keymacro_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ keymacro_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ keymacro_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+ keymacro_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+
+ if (el->el_map.type != MAP_VI)
+ return;
+ keymacro_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ keymacro_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ keymacro_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ keymacro_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ keymacro_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+ keymacro_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+ keymacro_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+ keymacro_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+ keymacro_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+ keymacro_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+ keymacro_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+ keymacro_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
}
-/* term_set_arrow():
+/* terminal_set_arrow():
* Set an arrow key binding
*/
protected int
-term_set_arrow(EditLine *el, const char *name, key_value_t *fun, int type)
+terminal_set_arrow(EditLine *el, const Char *name, keymacro_value_t *fun,
+ int type)
{
- fkey_t *arrow = el->el_term.t_fkey;
+ funckey_t *arrow = el->el_terminal.t_fkey;
int i;
for (i = 0; i < A_K_NKEYS; i++)
- if (strcmp(name, arrow[i].name) == 0) {
+ if (Strcmp(name, arrow[i].name) == 0) {
arrow[i].fun = *fun;
arrow[i].type = type;
- return (0);
+ return 0;
}
- return (-1);
+ return -1;
}
-/* term_clear_arrow():
+/* terminal_clear_arrow():
* Clear an arrow key binding
*/
protected int
-term_clear_arrow(EditLine *el, const char *name)
+terminal_clear_arrow(EditLine *el, const Char *name)
{
- fkey_t *arrow = el->el_term.t_fkey;
+ funckey_t *arrow = el->el_terminal.t_fkey;
int i;
for (i = 0; i < A_K_NKEYS; i++)
- if (strcmp(name, arrow[i].name) == 0) {
+ if (Strcmp(name, arrow[i].name) == 0) {
arrow[i].type = XK_NOD;
- return (0);
+ return 0;
}
- return (-1);
+ return -1;
}
-/* term_print_arrow():
+/* terminal_print_arrow():
* Print the arrow key bindings
*/
protected void
-term_print_arrow(EditLine *el, const char *name)
+terminal_print_arrow(EditLine *el, const Char *name)
{
int i;
- fkey_t *arrow = el->el_term.t_fkey;
+ funckey_t *arrow = el->el_terminal.t_fkey;
for (i = 0; i < A_K_NKEYS; i++)
- if (*name == '\0' || strcmp(name, arrow[i].name) == 0)
+ if (*name == '\0' || Strcmp(name, arrow[i].name) == 0)
if (arrow[i].type != XK_NOD)
- key_kprint(el, arrow[i].name, &arrow[i].fun,
- arrow[i].type);
+ keymacro_kprint(el, arrow[i].name,
+ &arrow[i].fun, arrow[i].type);
}
-/* term_bind_arrow():
+/* terminal_bind_arrow():
* Bind the arrow keys
*/
protected void
-term_bind_arrow(EditLine *el)
+terminal_bind_arrow(EditLine *el)
{
el_action_t *map;
const el_action_t *dmap;
int i, j;
char *p;
- fkey_t *arrow = el->el_term.t_fkey;
+ funckey_t *arrow = el->el_terminal.t_fkey;
/* Check if the components needed are initialized */
- if (el->el_term.t_buf == NULL || el->el_map.key == NULL)
+ if (el->el_terminal.t_buf == NULL || el->el_map.key == NULL)
return;
map = el->el_map.type == MAP_VI ? el->el_map.alt : el->el_map.key;
dmap = el->el_map.type == MAP_VI ? el->el_map.vic : el->el_map.emacs;
- term_reset_arrow(el);
+ terminal_reset_arrow(el);
for (i = 0; i < A_K_NKEYS; i++) {
- p = el->el_term.t_str[arrow[i].key];
- if (p && *p) {
- j = (unsigned char) *p;
- /*
- * Assign the arrow keys only if:
- *
- * 1. They are multi-character arrow keys and the user
- * has not re-assigned the leading character, or
- * has re-assigned the leading character to be
- * ED_SEQUENCE_LEAD_IN
- * 2. They are single arrow keys pointing to an
- * unassigned key.
- */
- if (arrow[i].type == XK_NOD)
- key_clear(el, map, p);
- else {
- if (p[1] && (dmap[j] == map[j] ||
- map[j] == ED_SEQUENCE_LEAD_IN)) {
- key_add(el, p, &arrow[i].fun,
+ Char wt_str[VISUAL_WIDTH_MAX];
+ Char *px;
+ size_t n;
+
+ p = el->el_terminal.t_str[arrow[i].key];
+ if (!p || !*p)
+ continue;
+ for (n = 0; n < VISUAL_WIDTH_MAX && p[n]; ++n)
+ wt_str[n] = p[n];
+ while (n < VISUAL_WIDTH_MAX)
+ wt_str[n++] = '\0';
+ px = wt_str;
+ j = (unsigned char) *p;
+ /*
+ * Assign the arrow keys only if:
+ *
+ * 1. They are multi-character arrow keys and the user
+ * has not re-assigned the leading character, or
+ * has re-assigned the leading character to be
+ * ED_SEQUENCE_LEAD_IN
+ * 2. They are single arrow keys pointing to an
+ * unassigned key.
+ */
+ if (arrow[i].type == XK_NOD)
+ keymacro_clear(el, map, px);
+ else {
+ if (p[1] && (dmap[j] == map[j] ||
+ map[j] == ED_SEQUENCE_LEAD_IN)) {
+ keymacro_add(el, px, &arrow[i].fun,
+ arrow[i].type);
+ map[j] = ED_SEQUENCE_LEAD_IN;
+ } else if (map[j] == ED_UNASSIGNED) {
+ keymacro_clear(el, map, px);
+ if (arrow[i].type == XK_CMD)
+ map[j] = arrow[i].fun.cmd;
+ else
+ keymacro_add(el, px, &arrow[i].fun,
arrow[i].type);
- map[j] = ED_SEQUENCE_LEAD_IN;
- } else if (map[j] == ED_UNASSIGNED) {
- key_clear(el, map, p);
- if (arrow[i].type == XK_CMD)
- map[j] = arrow[i].fun.cmd;
- else
- key_add(el, p, &arrow[i].fun,
- arrow[i].type);
- }
}
}
}
}
-/* term_putc():
+/* terminal_putc():
* Add a character
*/
private int
-term_putc(int c)
+terminal_putc(int c)
{
-
- if (term_outfile == NULL)
+ if (terminal_outfile == NULL)
return -1;
- return fputc(c, term_outfile);
+ return fputc(c, terminal_outfile);
}
private void
-term_tputs(EditLine *el, const char *cap, int affcnt)
+terminal_tputs(EditLine *el, const char *cap, int affcnt)
{
#ifdef _REENTRANT
- pthread_mutex_lock(&term_mutex);
+ pthread_mutex_lock(&terminal_mutex);
#endif
- term_outfile = el->el_outfile;
- (void)tputs(cap, affcnt, term_putc);
+ terminal_outfile = el->el_outfile;
+ (void)tputs(cap, affcnt, terminal_putc);
#ifdef _REENTRANT
- pthread_mutex_unlock(&term_mutex);
+ pthread_mutex_unlock(&terminal_mutex);
#endif
}
-/* term__putc():
+/* terminal__putc():
* Add a character
*/
protected int
-term__putc(EditLine *el, int c)
+terminal__putc(EditLine *el, Int c)
{
+ char buf[MB_LEN_MAX +1];
+ ssize_t i;
+ mbstate_t state;
- return fputc(c, el->el_outfile);
+ memset(&state, 0, sizeof(mbstate_t));
+ if (c == (Int)MB_FILL_CHAR)
+ return 0;
+ i = ct_encode_char(buf, (size_t)MB_CUR_MAX, c, &state);
+ if (i <= 0)
+ return (int)i;
+ buf[i] = '\0';
+ return fputs(buf, el->el_outfile);
}
-/* term__flush():
+/* terminal__flush():
* Flush output
*/
protected void
-term__flush(EditLine *el)
+terminal__flush(EditLine *el)
{
(void) fflush(el->el_outfile);
}
-/* term_writec():
+/* terminal_writec():
* Write the given character out, in a human readable form
*/
protected void
-term_writec(EditLine *el, int c)
+terminal_writec(EditLine *el, Int c)
{
- char buf[8];
- int cnt = key__decode_char(buf, sizeof(buf), 0, c);
- buf[cnt] = '\0';
- term_overwrite(el, buf, cnt);
- term__flush(el);
+ Char visbuf[VISUAL_WIDTH_MAX +1];
+ ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
+ visbuf[vcnt] = '\0';
+ terminal_overwrite(el, visbuf, (size_t)vcnt);
+ terminal__flush(el);
}
-/* term_telltc():
+/* terminal_telltc():
* Print the current termcap characteristics
*/
protected int
/*ARGSUSED*/
-term_telltc(EditLine *el, int argc __attribute__((__unused__)),
- const char **argv __attribute__((__unused__)))
+terminal_telltc(EditLine *el, int argc __attribute__((__unused__)),
+ const Char **argv __attribute__((__unused__)))
{
const struct termcapstr *t;
char **ts;
- char upbuf[EL_BUFSIZ];
(void) fprintf(el->el_outfile, "\n\tYour terminal has the\n");
(void) fprintf(el->el_outfile, "\tfollowing characteristics:\n\n");
@@ -1324,39 +1307,42 @@ term_telltc(EditLine *el, int argc __attribute__((__unused__)),
(void) fprintf(el->el_outfile, "\tIt %s magic margins\n",
EL_HAS_MAGIC_MARGINS ? "has" : "does not have");
- for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) {
+ for (t = tstr, ts = el->el_terminal.t_str; t->name != NULL; t++, ts++) {
const char *ub;
if (*ts && **ts) {
- (void) key__decode_str(*ts, upbuf, sizeof(upbuf), "");
- ub = upbuf;
+ ub = ct_encode_string(ct_visual_string(
+ ct_decode_string(*ts, &el->el_scratch)),
+ &el->el_scratch);
} else {
- ub = "(empty)";
+ ub = "(empty)";
}
(void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n",
t->long_name, t->name, ub);
}
(void) fputc('\n', el->el_outfile);
- return (0);
+ return 0;
}
-/* term_settc():
+/* terminal_settc():
* Change the current terminal characteristics
*/
protected int
/*ARGSUSED*/
-term_settc(EditLine *el, int argc __attribute__((__unused__)),
- const char **argv)
+terminal_settc(EditLine *el, int argc __attribute__((__unused__)),
+ const Char **argv)
{
const struct termcapstr *ts;
const struct termcapval *tv;
- const char *what, *how;
+ char what[8], how[8];
if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
return -1;
- what = argv[1];
- how = argv[2];
+ strncpy(what, ct_encode_string(argv[1], &el->el_scratch), sizeof(what));
+ what[sizeof(what) - 1] = '\0';
+ strncpy(how, ct_encode_string(argv[2], &el->el_scratch), sizeof(how));
+ how[sizeof(how) - 1] = '\0';
/*
* Do the strings first
@@ -1366,8 +1352,8 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)),
break;
if (ts->name != NULL) {
- term_alloc(el, ts, how);
- term_setflags(el);
+ terminal_alloc(el, ts, how);
+ terminal_setflags(el);
return 0;
}
/*
@@ -1383,16 +1369,16 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)),
if (tv == &tval[T_pt] || tv == &tval[T_km] ||
tv == &tval[T_am] || tv == &tval[T_xn]) {
if (strcmp(how, "yes") == 0)
- el->el_term.t_val[tv - tval] = 1;
+ el->el_terminal.t_val[tv - tval] = 1;
else if (strcmp(how, "no") == 0)
- el->el_term.t_val[tv - tval] = 0;
+ el->el_terminal.t_val[tv - tval] = 0;
else {
(void) fprintf(el->el_errfile,
- "%s: Bad value `%s'.\n", argv[0], how);
+ "" FSTR ": Bad value `%s'.\n", argv[0], how);
return -1;
}
- term_setflags(el);
- if (term_change_size(el, Val(T_li), Val(T_co)) == -1)
+ terminal_setflags(el);
+ if (terminal_change_size(el, Val(T_li), Val(T_co)) == -1)
return -1;
return 0;
} else {
@@ -1402,14 +1388,14 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)),
i = strtol(how, &ep, 10);
if (*ep != '\0') {
(void) fprintf(el->el_errfile,
- "%s: Bad value `%s'.\n", argv[0], how);
+ "" FSTR ": Bad value `%s'.\n", argv[0], how);
return -1;
}
- el->el_term.t_val[tv - tval] = (int) i;
- el->el_term.t_size.v = Val(T_co);
- el->el_term.t_size.h = Val(T_li);
+ el->el_terminal.t_val[tv - tval] = (int) i;
+ el->el_terminal.t_size.v = Val(T_co);
+ el->el_terminal.t_size.h = Val(T_li);
if (tv == &tval[T_co] || tv == &tval[T_li])
- if (term_change_size(el, Val(T_li), Val(T_co))
+ if (terminal_change_size(el, Val(T_li), Val(T_co))
== -1)
return -1;
return 0;
@@ -1417,12 +1403,12 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)),
}
-/* term_gettc():
+/* terminal_gettc():
* Get the current terminal characteristics
*/
protected int
/*ARGSUSED*/
-term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
+terminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
{
const struct termcapstr *ts;
const struct termcapval *tv;
@@ -1430,7 +1416,7 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
void *how;
if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
- return (-1);
+ return -1;
what = argv[1];
how = argv[2];
@@ -1443,7 +1429,7 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
break;
if (ts->name != NULL) {
- *(char **)how = el->el_term.t_str[ts - tstr];
+ *(char **)how = el->el_terminal.t_str[ts - tstr];
return 0;
}
/*
@@ -1460,26 +1446,27 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
tv == &tval[T_am] || tv == &tval[T_xn]) {
static char yes[] = "yes";
static char no[] = "no";
- if (el->el_term.t_val[tv - tval])
+ if (el->el_terminal.t_val[tv - tval])
*(char **)how = yes;
else
*(char **)how = no;
return 0;
} else {
- *(int *)how = el->el_term.t_val[tv - tval];
+ *(int *)how = el->el_terminal.t_val[tv - tval];
return 0;
}
}
-/* term_echotc():
+/* terminal_echotc():
* Print the termcap string out with variable substitution
*/
protected int
/*ARGSUSED*/
-term_echotc(EditLine *el, int argc __attribute__((__unused__)),
- const char **argv)
+terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
+ const Char **argv)
{
- char *cap, *scap, *ep;
+ char *cap, *scap;
+ Char *ep;
int arg_need, arg_cols, arg_rows;
int verbose = 0, silent = 0;
char *area;
@@ -1491,7 +1478,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
area = buf;
if (argv == NULL || argv[1] == NULL)
- return (-1);
+ return -1;
argv++;
if (argv[0][0] == '-') {
@@ -1509,62 +1496,52 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
argv++;
}
if (!*argv || *argv[0] == '\0')
- return (0);
- if (strcmp(*argv, "tabs") == 0) {
+ return 0;
+ if (Strcmp(*argv, STR("tabs")) == 0) {
(void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no");
- return (0);
- } else if (strcmp(*argv, "meta") == 0) {
+ return 0;
+ } else if (Strcmp(*argv, STR("meta")) == 0) {
(void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no");
- return (0);
- } else if (strcmp(*argv, "xn") == 0) {
+ return 0;
+ } else if (Strcmp(*argv, STR("xn")) == 0) {
(void) fprintf(el->el_outfile, fmts, EL_HAS_MAGIC_MARGINS ?
"yes" : "no");
- return (0);
- } else if (strcmp(*argv, "am") == 0) {
+ return 0;
+ } else if (Strcmp(*argv, STR("am")) == 0) {
(void) fprintf(el->el_outfile, fmts, EL_HAS_AUTO_MARGINS ?
"yes" : "no");
- return (0);
- } else if (strcmp(*argv, "baud") == 0) {
-#ifdef notdef
- int i;
-
- for (i = 0; baud_rate[i].b_name != NULL; i++)
- if (el->el_tty.t_speed == baud_rate[i].b_rate) {
- (void) fprintf(el->el_outfile, fmts,
- baud_rate[i].b_name);
- return (0);
- }
- (void) fprintf(el->el_outfile, fmtd, 0);
-#else
+ return 0;
+ } else if (Strcmp(*argv, STR("baud")) == 0) {
(void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed);
-#endif
- return (0);
- } else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) {
+ return 0;
+ } else if (Strcmp(*argv, STR("rows")) == 0 ||
+ Strcmp(*argv, STR("lines")) == 0) {
(void) fprintf(el->el_outfile, fmtd, Val(T_li));
- return (0);
- } else if (strcmp(*argv, "cols") == 0) {
+ return 0;
+ } else if (Strcmp(*argv, STR("cols")) == 0) {
(void) fprintf(el->el_outfile, fmtd, Val(T_co));
- return (0);
+ return 0;
}
/*
* Try to use our local definition first
*/
scap = NULL;
for (t = tstr; t->name != NULL; t++)
- if (strcmp(t->name, *argv) == 0) {
- scap = el->el_term.t_str[t - tstr];
+ if (strcmp(t->name,
+ ct_encode_string(*argv, &el->el_scratch)) == 0) {
+ scap = el->el_terminal.t_str[t - tstr];
break;
}
if (t->name == NULL) {
/* XXX: some systems' tgetstr needs non const */
- scap = tgetstr(strchr(*argv, **argv), &area);
+ scap = tgetstr(ct_encode_string(*argv, &el->el_scratch), &area);
}
if (!scap || scap[0] == '\0') {
if (!silent)
(void) fprintf(el->el_errfile,
- "echotc: Termcap parameter `%s' not found.\n",
+ "echotc: Termcap parameter `" FSTR "' not found.\n",
*argv);
- return (-1);
+ return -1;
}
/*
* Count home many values we need for this capability.
@@ -1605,11 +1582,11 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
if (*argv && *argv[0]) {
if (!silent)
(void) fprintf(el->el_errfile,
- "echotc: Warning: Extra argument `%s'.\n",
+ "echotc: Warning: Extra argument `" FSTR "'.\n",
*argv);
- return (-1);
+ return -1;
}
- term_tputs(el, scap, 1);
+ terminal_tputs(el, scap, 1);
break;
case 1:
argv++;
@@ -1617,27 +1594,27 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Warning: Missing argument.\n");
- return (-1);
+ return -1;
}
arg_cols = 0;
- i = strtol(*argv, &ep, 10);
+ i = Strtol(*argv, &ep, 10);
if (*ep != '\0' || i < 0) {
if (!silent)
(void) fprintf(el->el_errfile,
- "echotc: Bad value `%s' for rows.\n",
+ "echotc: Bad value `" FSTR "' for rows.\n",
*argv);
- return (-1);
+ return -1;
}
arg_rows = (int) i;
argv++;
if (*argv && *argv[0]) {
if (!silent)
(void) fprintf(el->el_errfile,
- "echotc: Warning: Extra argument `%s'.\n",
- *argv);
- return (-1);
+ "echotc: Warning: Extra argument `" FSTR
+ "'.\n", *argv);
+ return -1;
}
- term_tputs(el, tgoto(scap, arg_cols, arg_rows), 1);
+ terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), 1);
break;
default:
/* This is wrong, but I will ignore it... */
@@ -1652,15 +1629,15 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Warning: Missing argument.\n");
- return (-1);
+ return -1;
}
- i = strtol(*argv, &ep, 10);
+ i = Strtol(*argv, &ep, 10);
if (*ep != '\0' || i < 0) {
if (!silent)
(void) fprintf(el->el_errfile,
- "echotc: Bad value `%s' for cols.\n",
+ "echotc: Bad value `" FSTR "' for cols.\n",
*argv);
- return (-1);
+ return -1;
}
arg_cols = (int) i;
argv++;
@@ -1668,33 +1645,33 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Warning: Missing argument.\n");
- return (-1);
+ return -1;
}
- i = strtol(*argv, &ep, 10);
+ i = Strtol(*argv, &ep, 10);
if (*ep != '\0' || i < 0) {
if (!silent)
(void) fprintf(el->el_errfile,
- "echotc: Bad value `%s' for rows.\n",
+ "echotc: Bad value `" FSTR "' for rows.\n",
*argv);
- return (-1);
+ return -1;
}
arg_rows = (int) i;
if (*ep != '\0') {
if (!silent)
(void) fprintf(el->el_errfile,
- "echotc: Bad value `%s'.\n", *argv);
- return (-1);
+ "echotc: Bad value `" FSTR "'.\n", *argv);
+ return -1;
}
argv++;
if (*argv && *argv[0]) {
if (!silent)
(void) fprintf(el->el_errfile,
- "echotc: Warning: Extra argument `%s'.\n",
- *argv);
- return (-1);
+ "echotc: Warning: Extra argument `" FSTR
+ "'.\n", *argv);
+ return -1;
}
- term_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows);
+ terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows);
break;
}
- return (0);
+ return 0;
}
diff --git a/cmd-line-utils/libedit/tokenizer.c b/cmd-line-utils/libedit/tokenizer.c
index 5161cdd0a22..7267164e9b6 100644
--- a/cmd-line-utils/libedit/tokenizer.c
+++ b/cmd-line-utils/libedit/tokenizer.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $ */
+/* $NetBSD: tokenizer.c,v 1.19 2011/07/28 20:50:55 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,51 +40,53 @@ static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
#endif
#endif /* not lint && not SCCSID */
+/* We build this file twice, once as NARROW, once as WIDE. */
/*
* tokenize.c: Bourne shell like tokenizer
*/
#include <string.h>
#include <stdlib.h>
#include "histedit.h"
+#include "chartype.h"
typedef enum {
Q_none, Q_single, Q_double, Q_one, Q_doubleone
} quote_t;
-#define IFS "\t \n"
-
#define TOK_KEEP 1
#define TOK_EAT 2
#define WINCR 20
#define AINCR 10
-#define tok_strdup(a) strdup(a)
+#define IFS STR("\t \n")
+
#define tok_malloc(a) malloc(a)
#define tok_free(a) free(a)
#define tok_realloc(a, b) realloc(a, b)
+#define tok_strdup(a) Strdup(a)
-struct tokenizer {
- char *ifs; /* In field separator */
+struct TYPE(tokenizer) {
+ Char *ifs; /* In field separator */
int argc, amax; /* Current and maximum number of args */
- char **argv; /* Argument list */
- char *wptr, *wmax; /* Space and limit on the word buffer */
- char *wstart; /* Beginning of next word */
- char *wspace; /* Space of word buffer */
+ Char **argv; /* Argument list */
+ Char *wptr, *wmax; /* Space and limit on the word buffer */
+ Char *wstart; /* Beginning of next word */
+ Char *wspace; /* Space of word buffer */
quote_t quote; /* Quoting state */
int flags; /* flags; */
};
-private void tok_finish(Tokenizer *);
+private void FUN(tok,finish)(TYPE(Tokenizer) *);
-/* tok_finish():
+/* FUN(tok,finish)():
* Finish a word in the tokenizer.
*/
private void
-tok_finish(Tokenizer *tok)
+FUN(tok,finish)(TYPE(Tokenizer) *tok)
{
*tok->wptr = '\0';
@@ -97,35 +99,35 @@ tok_finish(Tokenizer *tok)
}
-/* tok_init():
+/* FUN(tok,init)():
* Initialize the tokenizer
*/
-public Tokenizer *
-tok_init(const char *ifs)
+public TYPE(Tokenizer) *
+FUN(tok,init)(const Char *ifs)
{
- Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer));
+ TYPE(Tokenizer) *tok = tok_malloc(sizeof(*tok));
if (tok == NULL)
return NULL;
tok->ifs = tok_strdup(ifs ? ifs : IFS);
if (tok->ifs == NULL) {
- tok_free((ptr_t)tok);
+ tok_free(tok);
return NULL;
}
tok->argc = 0;
tok->amax = AINCR;
- tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax);
+ tok->argv = tok_malloc(sizeof(*tok->argv) * tok->amax);
if (tok->argv == NULL) {
- tok_free((ptr_t)tok->ifs);
- tok_free((ptr_t)tok);
+ tok_free(tok->ifs);
+ tok_free(tok);
return NULL;
}
tok->argv[0] = NULL;
- tok->wspace = (char *) tok_malloc(WINCR);
+ tok->wspace = tok_malloc(WINCR * sizeof(*tok->wspace));
if (tok->wspace == NULL) {
- tok_free((ptr_t)tok->argv);
- tok_free((ptr_t)tok->ifs);
- tok_free((ptr_t)tok);
+ tok_free(tok->argv);
+ tok_free(tok->ifs);
+ tok_free(tok);
return NULL;
}
tok->wmax = tok->wspace + WINCR;
@@ -138,11 +140,11 @@ tok_init(const char *ifs)
}
-/* tok_reset():
+/* FUN(tok,reset)():
* Reset the tokenizer
*/
public void
-tok_reset(Tokenizer *tok)
+FUN(tok,reset)(TYPE(Tokenizer) *tok)
{
tok->argc = 0;
@@ -153,25 +155,25 @@ tok_reset(Tokenizer *tok)
}
-/* tok_end():
+/* FUN(tok,end)():
* Clean up
*/
public void
-tok_end(Tokenizer *tok)
+FUN(tok,end)(TYPE(Tokenizer) *tok)
{
- tok_free((ptr_t) tok->ifs);
- tok_free((ptr_t) tok->wspace);
- tok_free((ptr_t) tok->argv);
- tok_free((ptr_t) tok);
+ tok_free(tok->ifs);
+ tok_free(tok->wspace);
+ tok_free(tok->argv);
+ tok_free(tok);
}
-/* tok_line():
+/* FUN(tok,line)():
* Bourne shell (sh(1)) like tokenizing
* Arguments:
- * tok current tokenizer state (setup with tok_init())
+ * tok current tokenizer state (setup with FUN(tok,init)())
* line line to parse
* Returns:
* -1 Internal error
@@ -186,20 +188,20 @@ tok_end(Tokenizer *tok)
* cursorv if !NULL, offset in argv[cursorc] of cursor
*/
public int
-tok_line(Tokenizer *tok, const LineInfo *line,
- int *argc, const char ***argv, int *cursorc, int *cursoro)
+FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
+ int *argc, const Char ***argv, int *cursorc, int *cursoro)
{
- const char *ptr;
+ const Char *ptr;
int cc, co;
cc = co = -1;
ptr = line->buffer;
for (ptr = line->buffer; ;ptr++) {
if (ptr >= line->lastchar)
- ptr = "";
+ ptr = STR("");
if (ptr == line->cursor) {
cc = tok->argc;
- co = tok->wptr - tok->wstart;
+ co = (int)(tok->wptr - tok->wstart);
}
switch (*ptr) {
case '\'':
@@ -357,8 +359,8 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok->flags &= ~TOK_EAT;
switch (tok->quote) {
case Q_none:
- if (strchr(tok->ifs, *ptr) != NULL)
- tok_finish(tok);
+ if (Strchr(tok->ifs, *ptr) != NULL)
+ FUN(tok,finish)(tok);
else
*tok->wptr++ = *ptr;
break;
@@ -389,7 +391,8 @@ tok_line(Tokenizer *tok, const LineInfo *line,
if (tok->wptr >= tok->wmax - 4) {
size_t size = tok->wmax - tok->wspace + WINCR;
- char *s = (char *) tok_realloc(tok->wspace, size);
+ Char *s = tok_realloc(tok->wspace,
+ size * sizeof(*s));
if (s == NULL)
return (-1);
@@ -406,10 +409,9 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok->wmax = s + size;
}
if (tok->argc >= tok->amax - 4) {
- char **p;
+ Char **p;
tok->amax += AINCR;
- p = (char **) tok_realloc(tok->argv,
- tok->amax * sizeof(char *));
+ p = tok_realloc(tok->argv, tok->amax * sizeof(*p));
if (p == NULL)
return (-1);
tok->argv = p;
@@ -418,29 +420,30 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok_line_outok:
if (cc == -1 && co == -1) {
cc = tok->argc;
- co = tok->wptr - tok->wstart;
+ co = (int)(tok->wptr - tok->wstart);
}
if (cursorc != NULL)
*cursorc = cc;
if (cursoro != NULL)
*cursoro = co;
- tok_finish(tok);
- *argv = (const char **)tok->argv;
+ FUN(tok,finish)(tok);
+ *argv = (const Char **)tok->argv;
*argc = tok->argc;
return (0);
}
-/* tok_str():
+/* FUN(tok,str)():
* Simpler version of tok_line, taking a NUL terminated line
* and splitting into words, ignoring cursor state.
*/
public int
-tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv)
+FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc,
+ const Char ***argv)
{
- LineInfo li;
+ TYPE(LineInfo) li;
memset(&li, 0, sizeof(li));
li.buffer = line;
- li.cursor = li.lastchar = strchr(line, '\0');
- return (tok_line(tok, &li, argc, argv, NULL, NULL));
+ li.cursor = li.lastchar = Strchr(line, '\0');
+ return (FUN(tok,line)(tok, &li, argc, argv, NULL, NULL));
}
diff --git a/cmd-line-utils/libedit/tokenizern.c b/cmd-line-utils/libedit/tokenizern.c
new file mode 100644
index 00000000000..92376e066f1
--- /dev/null
+++ b/cmd-line-utils/libedit/tokenizern.c
@@ -0,0 +1,5 @@
+#define NARROW_WRAPPER
+#include "config.h"
+#undef WIDECHAR
+#define NARROWCHAR
+#include "./tokenizer.c"
diff --git a/cmd-line-utils/libedit/tty.c b/cmd-line-utils/libedit/tty.c
index 3706905fc79..eea00bfc245 100644
--- a/cmd-line-utils/libedit/tty.c
+++ b/cmd-line-utils/libedit/tty.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tty.c,v 1.28 2009/02/06 19:53:23 sketch Exp $ */
+/* $NetBSD: tty.c,v 1.41 2011/10/04 15:27:04 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -45,8 +45,10 @@ static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
*/
#include <assert.h>
#include <errno.h>
-#include "tty.h"
+#include <unistd.h> /* for isatty */
+#include <strings.h> /* for ffs */
#include "el.h"
+#include "tty.h"
typedef struct ttymodes_t {
const char *m_name;
@@ -55,7 +57,7 @@ typedef struct ttymodes_t {
} ttymodes_t;
typedef struct ttymap_t {
- int nch, och; /* Internal and termio rep of chars */
+ Int nch, och; /* Internal and termio rep of chars */
el_action_t bind[3]; /* emacs, vi, and vi-cmd */
} ttymap_t;
@@ -151,7 +153,7 @@ private const ttymap_t tty_map[] = {
{C_LNEXT, VLNEXT,
{ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
#endif /* VLNEXT */
- {-1, -1,
+ {(Int)-1, (Int)-1,
{ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
};
@@ -492,14 +494,21 @@ tty_setup(EditLine *el)
int rst = 1;
if (el->el_flags & EDIT_DISABLED)
- return (0);
+ return 0;
+ if (!isatty(el->el_outfd)) {
+#ifdef DEBUG_TTY
+ (void) fprintf(el->el_errfile,
+ "tty_setup: isatty: %s\n", strerror(errno));
+#endif /* DEBUG_TTY */
+ return -1;
+ }
if (tty_getty(el, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_setup: tty_getty: %s\n", strerror(errno));
#endif /* DEBUG_TTY */
- return (-1);
+ return -1;
}
el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
@@ -549,13 +558,9 @@ tty_setup(EditLine *el)
"tty_setup: tty_setty: %s\n",
strerror(errno));
#endif /* DEBUG_TTY */
- return (-1);
+ return -1;
}
}
-#ifdef notdef
- else
- tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
-#endif
el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
@@ -571,7 +576,7 @@ tty_setup(EditLine *el)
tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
tty_bind_char(el, 1);
- return (0);
+ return 0;
}
protected int
@@ -582,7 +587,7 @@ tty_init(EditLine *el)
el->el_tty.t_vdisable = _POSIX_VDISABLE;
(void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
(void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
- return (tty_setup(el));
+ return tty_setup(el);
}
@@ -608,7 +613,7 @@ tty__getspeed(struct termios *td)
if ((spd = cfgetispeed(td)) == 0)
spd = cfgetospeed(td);
- return (spd);
+ return spd;
}
/* tty__getspeed():
@@ -892,7 +897,7 @@ tty_bind_char(EditLine *el, int force)
unsigned char *t_n = el->el_tty.t_c[ED_IO];
unsigned char *t_o = el->el_tty.t_ed.c_cc;
- unsigned char new[2], old[2];
+ Char new[2], old[2];
const ttymap_t *tp;
el_action_t *map, *alt;
const el_action_t *dmap, *dalt;
@@ -908,22 +913,22 @@ tty_bind_char(EditLine *el, int force)
dalt = NULL;
}
- for (tp = tty_map; tp->nch != -1; tp++) {
+ for (tp = tty_map; tp->nch != (Int)-1; tp++) {
new[0] = t_n[tp->nch];
old[0] = t_o[tp->och];
if (new[0] == old[0] && !force)
continue;
/* Put the old default binding back, and set the new binding */
- key_clear(el, map, (char *)old);
- map[old[0]] = dmap[old[0]];
- key_clear(el, map, (char *)new);
+ keymacro_clear(el, map, old);
+ map[UC(old[0])] = dmap[UC(old[0])];
+ keymacro_clear(el, map, new);
/* MAP_VI == 1, MAP_EMACS == 0... */
- map[new[0]] = tp->bind[el->el_map.type];
+ map[UC(new[0])] = tp->bind[el->el_map.type];
if (dalt) {
- key_clear(el, alt, (char *)old);
- alt[old[0]] = dalt[old[0]];
- key_clear(el, alt, (char *)new);
- alt[new[0]] = tp->bind[el->el_map.type + 1];
+ keymacro_clear(el, alt, old);
+ alt[UC(old[0])] = dalt[UC(old[0])];
+ keymacro_clear(el, alt, new);
+ alt[UC(new[0])] = tp->bind[el->el_map.type + 1];
}
}
}
@@ -937,21 +942,21 @@ tty_rawmode(EditLine *el)
{
if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
- return (0);
+ return 0;
if (el->el_flags & EDIT_DISABLED)
- return (0);
+ return 0;
if (tty_getty(el, &el->el_tty.t_ts) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n",
strerror(errno));
#endif /* DEBUG_TTY */
- return (-1);
+ return -1;
}
/*
* We always keep up with the eight bit setting and the speed of the
- * tty. But only we only believe changes that are made to cooked mode!
+ * tty. But we only believe changes that are made to cooked mode!
*/
el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts);
el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
@@ -1077,10 +1082,10 @@ tty_rawmode(EditLine *el)
(void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
strerror(errno));
#endif /* DEBUG_TTY */
- return (-1);
+ return -1;
}
el->el_tty.t_mode = ED_IO;
- return (0);
+ return 0;
}
@@ -1092,10 +1097,10 @@ tty_cookedmode(EditLine *el)
{ /* set tty in normal setup */
if (el->el_tty.t_mode == EX_IO)
- return (0);
+ return 0;
if (el->el_flags & EDIT_DISABLED)
- return (0);
+ return 0;
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY
@@ -1103,10 +1108,10 @@ tty_cookedmode(EditLine *el)
"tty_cookedmode: tty_setty: %s\n",
strerror(errno));
#endif /* DEBUG_TTY */
- return (-1);
+ return -1;
}
el->el_tty.t_mode = EX_IO;
- return (0);
+ return 0;
}
@@ -1117,7 +1122,7 @@ protected int
tty_quotemode(EditLine *el)
{
if (el->el_tty.t_mode == QU_IO)
- return (0);
+ return 0;
el->el_tty.t_qu = el->el_tty.t_ed;
@@ -1138,10 +1143,10 @@ tty_quotemode(EditLine *el)
(void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
strerror(errno));
#endif /* DEBUG_TTY */
- return (-1);
+ return -1;
}
el->el_tty.t_mode = QU_IO;
- return (0);
+ return 0;
}
@@ -1153,16 +1158,16 @@ tty_noquotemode(EditLine *el)
{
if (el->el_tty.t_mode != QU_IO)
- return (0);
+ return 0;
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
strerror(errno));
#endif /* DEBUG_TTY */
- return (-1);
+ return -1;
}
el->el_tty.t_mode = ED_IO;
- return (0);
+ return 0;
}
@@ -1171,19 +1176,20 @@ tty_noquotemode(EditLine *el)
*/
protected int
/*ARGSUSED*/
-tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
+tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
{
const ttymodes_t *m;
char x;
int aflag = 0;
- const char *s, *d;
- const char *name;
+ const Char *s, *d;
+ char name[EL_BUFSIZ];
struct termios *tios = &el->el_tty.t_ex;
int z = EX_IO;
if (argv == NULL)
- return (-1);
- name = *argv++;
+ return -1;
+ strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name));
+ name[sizeof(name) - 1] = '\0';
while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
switch (argv[0][1]) {
@@ -1209,13 +1215,13 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
default:
(void) fprintf(el->el_errfile,
"%s: Unknown switch `%c'.\n",
- name, argv[0][1]);
- return (-1);
+ name, (int) argv[0][1]);
+ return -1;
}
if (!argv || !*argv) {
int i = -1;
- int len = 0, st = 0, cu;
+ size_t len = 0, st = 0, cu;
for (m = ttymodes; m->m_name; m++) {
if (m->m_type != i) {
(void) fprintf(el->el_outfile, "%s%s",
@@ -1228,8 +1234,9 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
if (i != -1) {
x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
? '+' : '\0';
- x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
- ? '-' : x;
+
+ if (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
+ x = '-';
} else {
x = '\0';
}
@@ -1238,9 +1245,9 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
cu = strlen(m->m_name) + (x != '\0') + 1;
- if (len + cu >= el->el_term.t_size.h) {
+ if (len + cu >= (size_t)el->el_terminal.t_size.h) {
(void) fprintf(el->el_outfile, "\n%*s",
- st, "");
+ (int)st, "");
len = st + cu;
} else
len += cu;
@@ -1254,40 +1261,41 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
}
}
(void) fprintf(el->el_outfile, "\n");
- return (0);
+ return 0;
}
while (argv && (s = *argv++)) {
- const char *p;
+ const Char *p;
switch (*s) {
case '+':
case '-':
- x = *s++;
+ x = (char)*s++;
break;
default:
x = '\0';
break;
}
d = s;
- p = strchr(s, '=');
+ p = Strchr(s, '=');
for (m = ttymodes; m->m_name; m++)
- if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) :
- strcmp(m->m_name, d)) == 0 &&
+ if ((p ? strncmp(m->m_name, ct_encode_string(d, &el->el_scratch), (size_t)(p - d)) :
+ strcmp(m->m_name, ct_encode_string(d, &el->el_scratch))) == 0 &&
(p == NULL || m->m_type == MD_CHAR))
break;
if (!m->m_name) {
(void) fprintf(el->el_errfile,
- "%s: Invalid argument `%s'.\n", name, d);
- return (-1);
+ "%s: Invalid argument `" FSTR "'.\n", name, d);
+ return -1;
}
if (p) {
int c = ffs((int)m->m_value);
- int v = *++p ? parse__escape((const char **) &p) :
+ int v = *++p ? parse__escape(&p) :
el->el_tty.t_vdisable;
- assert(c-- != 0);
+ assert(c != 0);
+ c--;
c = tty__getcharindex(c);
assert(c != -1);
- tios->c_cc[c] = v;
+ tios->c_cc[c] = (cc_t)v;
continue;
}
switch (x) {
@@ -1312,11 +1320,11 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
(void) fprintf(el->el_errfile,
"tty_stty: tty_setty: %s\n", strerror(errno));
#endif /* DEBUG_TTY */
- return (-1);
+ return -1;
}
}
- return (0);
+ return 0;
}
diff --git a/cmd-line-utils/libedit/tty.h b/cmd-line-utils/libedit/tty.h
index 10e9b98c953..04485eb83ad 100644
--- a/cmd-line-utils/libedit/tty.h
+++ b/cmd-line-utils/libedit/tty.h
@@ -1,4 +1,4 @@
-/* $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $ */
+/* $NetBSD: tty.h,v 1.13 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,6 +40,7 @@
#ifndef _h_el_tty
#define _h_el_tty
+#include "sys.h"
#include "histedit.h"
#include <termios.h>
#include <unistd.h>
@@ -430,7 +431,7 @@
#define C_MIN 23
#define C_TIME 24
#define C_NCC 25
-#define C_SH(A) (1 << (A))
+#define C_SH(A) ((unsigned int)(1 << (A)))
/*
* Terminal dependend data structures
@@ -458,7 +459,7 @@ typedef unsigned char ttychar_t[NN_IO][C_NCC];
protected int tty_init(EditLine *);
protected void tty_end(EditLine *);
-protected int tty_stty(EditLine *, int, const char **);
+protected int tty_stty(EditLine *, int, const Char **);
protected int tty_rawmode(EditLine *);
protected int tty_cookedmode(EditLine *);
protected int tty_quotemode(EditLine *);
diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c
index beffc7b40b5..9a4b97a977e 100644
--- a/cmd-line-utils/libedit/vi.c
+++ b/cmd-line-utils/libedit/vi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vi.c,v 1.28 2009/02/06 13:14:37 sketch Exp $ */
+/* $NetBSD: vi.c,v 1.41 2011/10/04 15:27:04 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -35,6 +35,7 @@
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
+#include <limits.h>
#include <sys/wait.h>
#if !defined(lint) && !defined(SCCSID)
@@ -49,25 +50,25 @@ static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
*/
#include "el.h"
-private el_action_t cv_action(EditLine *, int);
-private el_action_t cv_paste(EditLine *, int);
+private el_action_t cv_action(EditLine *, Int);
+private el_action_t cv_paste(EditLine *, Int);
/* cv_action():
* Handle vi actions.
*/
private el_action_t
-cv_action(EditLine *el, int c)
+cv_action(EditLine *el, Int c)
{
if (el->el_chared.c_vcmd.action != NOP) {
/* 'cc', 'dd' and (possibly) friends */
- if (c != el->el_chared.c_vcmd.action)
+ if (c != (Int)el->el_chared.c_vcmd.action)
return CC_ERROR;
if (!(c & YANK))
cv_undo(el);
cv_yank(el, el->el_line.buffer,
- el->el_line.lastchar - el->el_line.buffer);
+ (int)(el->el_line.lastchar - el->el_line.buffer));
el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = 0;
if (!(c & YANK)) {
@@ -77,26 +78,26 @@ cv_action(EditLine *el, int c)
if (c & INSERT)
el->el_map.current = el->el_map.key;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
el->el_chared.c_vcmd.pos = el->el_line.cursor;
el->el_chared.c_vcmd.action = c;
- return (CC_ARGHACK);
+ return CC_ARGHACK;
}
/* cv_paste():
* Paste previous deletion before or after the cursor
*/
private el_action_t
-cv_paste(EditLine *el, int c)
+cv_paste(EditLine *el, Int c)
{
c_kill_t *k = &el->el_chared.c_kill;
- int len = k->last - k->buf;
+ size_t len = (size_t)(k->last - k->buf);
if (k->buf == NULL || len == 0)
- return (CC_ERROR);
+ return CC_ERROR;
#ifdef DEBUG_PASTE
- (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", len, k->buf);
+ (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf);
#endif
cv_undo(el);
@@ -104,12 +105,13 @@ cv_paste(EditLine *el, int c)
if (!c && el->el_line.cursor < el->el_line.lastchar)
el->el_line.cursor++;
- c_insert(el, len);
+ c_insert(el, (int)len);
if (el->el_line.cursor + len > el->el_line.lastchar)
- return (CC_ERROR);
- (void) memcpy(el->el_line.cursor, k->buf, len +0u);
+ return CC_ERROR;
+ (void) memcpy(el->el_line.cursor, k->buf, len *
+ sizeof(*el->el_line.cursor));
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -119,10 +121,10 @@ cv_paste(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-vi_paste_next(EditLine *el, int c __attribute__((__unused__)))
+vi_paste_next(EditLine *el, Int c __attribute__((__unused__)))
{
- return (cv_paste(el, 0));
+ return cv_paste(el, 0);
}
@@ -132,10 +134,10 @@ vi_paste_next(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_paste_prev(EditLine *el, int c __attribute__((__unused__)))
+vi_paste_prev(EditLine *el, Int c __attribute__((__unused__)))
{
- return (cv_paste(el, 1));
+ return cv_paste(el, 1);
}
@@ -145,11 +147,11 @@ vi_paste_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_prev_big_word(EditLine *el, int c __attribute__((__unused__)))
+vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_line.cursor = cv_prev_word(el->el_line.cursor,
el->el_line.buffer,
@@ -158,9 +160,9 @@ vi_prev_big_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -170,11 +172,11 @@ vi_prev_big_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
+vi_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_line.cursor = cv_prev_word(el->el_line.cursor,
el->el_line.buffer,
@@ -183,9 +185,9 @@ vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -195,11 +197,11 @@ vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_next_big_word(EditLine *el, int c __attribute__((__unused__)))
+vi_next_big_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar - 1)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isWord);
@@ -207,9 +209,9 @@ vi_next_big_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -219,11 +221,11 @@ vi_next_big_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_next_word(EditLine *el, int c __attribute__((__unused__)))
+vi_next_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar - 1)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isword);
@@ -231,9 +233,9 @@ vi_next_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -242,20 +244,20 @@ vi_next_word(EditLine *el, int c __attribute__((__unused__)))
* [~]
*/
protected el_action_t
-vi_change_case(EditLine *el, int c)
+vi_change_case(EditLine *el, Int c)
{
int i;
if (el->el_line.cursor >= el->el_line.lastchar)
- return (CC_ERROR);
+ return CC_ERROR;
cv_undo(el);
for (i = 0; i < el->el_state.argument; i++) {
- c = *(unsigned char *)el->el_line.cursor;
- if (isupper(c))
- *el->el_line.cursor = tolower(c);
- else if (islower(c))
- *el->el_line.cursor = toupper(c);
+ c = *el->el_line.cursor;
+ if (Isupper(c))
+ *el->el_line.cursor = Tolower(c);
+ else if (Islower(c))
+ *el->el_line.cursor = Toupper(c);
if (++el->el_line.cursor >= el->el_line.lastchar) {
el->el_line.cursor--;
@@ -274,14 +276,14 @@ vi_change_case(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-vi_change_meta(EditLine *el, int c __attribute__((__unused__)))
+vi_change_meta(EditLine *el, Int c __attribute__((__unused__)))
{
/*
* Delete with insert == change: first we delete and then we leave in
* insert mode.
*/
- return (cv_action(el, DELETE | INSERT));
+ return cv_action(el, DELETE | INSERT);
}
@@ -291,13 +293,13 @@ vi_change_meta(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__)))
+vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
cv_undo(el);
el->el_map.current = el->el_map.key;
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -307,7 +309,7 @@ vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
+vi_replace_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar)
@@ -316,7 +318,7 @@ vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
el->el_map.current = el->el_map.key;
el->el_state.inputmode = MODE_REPLACE_1;
cv_undo(el);
- return (CC_ARGHACK);
+ return CC_ARGHACK;
}
@@ -326,13 +328,13 @@ vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_replace_mode(EditLine *el, int c __attribute__((__unused__)))
+vi_replace_mode(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
el->el_state.inputmode = MODE_REPLACE;
cv_undo(el);
- return (CC_NORM);
+ return CC_NORM;
}
@@ -342,12 +344,12 @@ vi_replace_mode(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_substitute_char(EditLine *el, int c __attribute__((__unused__)))
+vi_substitute_char(EditLine *el, Int c __attribute__((__unused__)))
{
c_delafter(el, el->el_state.argument);
el->el_map.current = el->el_map.key;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -357,15 +359,15 @@ vi_substitute_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_substitute_line(EditLine *el, int c __attribute__((__unused__)))
+vi_substitute_line(EditLine *el, Int c __attribute__((__unused__)))
{
cv_undo(el);
cv_yank(el, el->el_line.buffer,
- el->el_line.lastchar - el->el_line.buffer);
+ (int)(el->el_line.lastchar - el->el_line.buffer));
(void) em_kill_line(el, 0);
el->el_map.current = el->el_map.key;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -375,15 +377,15 @@ vi_substitute_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_change_to_eol(EditLine *el, int c __attribute__((__unused__)))
+vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__)))
{
cv_undo(el);
cv_yank(el, el->el_line.cursor,
- el->el_line.lastchar - el->el_line.cursor);
+ (int)(el->el_line.lastchar - el->el_line.cursor));
(void) ed_kill_line(el, 0);
el->el_map.current = el->el_map.key;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -393,12 +395,12 @@ vi_change_to_eol(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_insert(EditLine *el, int c __attribute__((__unused__)))
+vi_insert(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
cv_undo(el);
- return (CC_NORM);
+ return CC_NORM;
}
@@ -408,7 +410,7 @@ vi_insert(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_add(EditLine *el, int c __attribute__((__unused__)))
+vi_add(EditLine *el, Int c __attribute__((__unused__)))
{
int ret;
@@ -423,7 +425,7 @@ vi_add(EditLine *el, int c __attribute__((__unused__)))
cv_undo(el);
- return (ret);
+ return (el_action_t)ret;
}
@@ -433,13 +435,13 @@ vi_add(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_add_at_eol(EditLine *el, int c __attribute__((__unused__)))
+vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
el->el_line.cursor = el->el_line.lastchar;
cv_undo(el);
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -449,10 +451,10 @@ vi_add_at_eol(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_delete_meta(EditLine *el, int c __attribute__((__unused__)))
+vi_delete_meta(EditLine *el, Int c __attribute__((__unused__)))
{
- return (cv_action(el, DELETE));
+ return cv_action(el, DELETE);
}
@@ -462,11 +464,11 @@ vi_delete_meta(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_end_big_word(EditLine *el, int c __attribute__((__unused__)))
+vi_end_big_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_line.cursor = cv__endword(el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isWord);
@@ -474,9 +476,9 @@ vi_end_big_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_chared.c_vcmd.action != NOP) {
el->el_line.cursor++;
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -486,11 +488,11 @@ vi_end_big_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_end_word(EditLine *el, int c __attribute__((__unused__)))
+vi_end_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
- return (CC_ERROR);
+ return CC_ERROR;
el->el_line.cursor = cv__endword(el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isword);
@@ -498,9 +500,9 @@ vi_end_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_chared.c_vcmd.action != NOP) {
el->el_line.cursor++;
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -510,7 +512,7 @@ vi_end_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_undo(EditLine *el, int c __attribute__((__unused__)))
+vi_undo(EditLine *el, Int c __attribute__((__unused__)))
{
c_undo_t un = el->el_chared.c_undo;
@@ -520,13 +522,14 @@ vi_undo(EditLine *el, int c __attribute__((__unused__)))
/* switch line buffer and undo buffer */
el->el_chared.c_undo.buf = el->el_line.buffer;
el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
- el->el_chared.c_undo.cursor = el->el_line.cursor - el->el_line.buffer;
+ el->el_chared.c_undo.cursor =
+ (int)(el->el_line.cursor - el->el_line.buffer);
el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
el->el_line.buffer = un.buf;
el->el_line.cursor = un.buf + un.cursor;
el->el_line.lastchar = un.buf + un.len;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -536,7 +539,7 @@ vi_undo(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
+vi_command_mode(EditLine *el, Int c __attribute__((__unused__)))
{
/* [Esc] cancels pending action */
@@ -551,7 +554,7 @@ vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
if (el->el_line.cursor > el->el_line.buffer)
el->el_line.cursor--;
#endif
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -560,7 +563,7 @@ vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
* [0]
*/
protected el_action_t
-vi_zero(EditLine *el, int c)
+vi_zero(EditLine *el, Int c)
{
if (el->el_state.doingarg)
@@ -569,9 +572,9 @@ vi_zero(EditLine *el, int c)
el->el_line.cursor = el->el_line.buffer;
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
@@ -581,15 +584,15 @@ vi_zero(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
+vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
- return (CC_ERROR);
+ return CC_ERROR;
c_delbefore1(el);
el->el_line.cursor--;
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -599,32 +602,32 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_list_or_eof(EditLine *el, int c)
+vi_list_or_eof(EditLine *el, Int c)
{
if (el->el_line.cursor == el->el_line.lastchar) {
if (el->el_line.cursor == el->el_line.buffer) {
- term_writec(el, c); /* then do a EOF */
- return (CC_EOF);
+ terminal_writec(el, c); /* then do a EOF */
+ return CC_EOF;
} else {
/*
* Here we could list completions, but it is an
* error right now
*/
- term_beep(el);
- return (CC_ERROR);
+ terminal_beep(el);
+ return CC_ERROR;
}
} else {
#ifdef notyet
re_goto_bottom(el);
*el->el_line.lastchar = '\0'; /* just in case */
- return (CC_LIST_CHOICES);
+ return CC_LIST_CHOICES;
#else
/*
* Just complain for now.
*/
- term_beep(el);
- return (CC_ERROR);
+ terminal_beep(el);
+ return CC_ERROR;
#endif
}
}
@@ -636,18 +639,18 @@ vi_list_or_eof(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
-vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__)))
+vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__)))
{
- char *kp, *cp;
+ Char *kp, *cp;
cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf;
while (cp < el->el_line.cursor)
*kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp;
- c_delbefore(el, el->el_line.cursor - el->el_line.buffer);
+ c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer));
el->el_line.cursor = el->el_line.buffer; /* zap! */
- return (CC_REFRESH);
+ return CC_REFRESH;
}
@@ -657,10 +660,10 @@ vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_search_prev(EditLine *el, int c __attribute__((__unused__)))
+vi_search_prev(EditLine *el, Int c __attribute__((__unused__)))
{
- return (cv_search(el, ED_SEARCH_PREV_HISTORY));
+ return cv_search(el, ED_SEARCH_PREV_HISTORY);
}
@@ -670,10 +673,10 @@ vi_search_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_search_next(EditLine *el, int c __attribute__((__unused__)))
+vi_search_next(EditLine *el, Int c __attribute__((__unused__)))
{
- return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
+ return cv_search(el, ED_SEARCH_NEXT_HISTORY);
}
@@ -683,13 +686,13 @@ vi_search_next(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__)))
+vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_search.patlen == 0)
- return (CC_ERROR);
+ return CC_ERROR;
else
- return (cv_repeat_srch(el, el->el_search.patdir));
+ return cv_repeat_srch(el, el->el_search.patdir);
}
@@ -699,11 +702,11 @@ vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__)))
*/
/*ARGSUSED*/
protected el_action_t
-vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__)))
+vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_search.patlen == 0)
- return (CC_ERROR);
+ return CC_ERROR;
else
return (cv_repeat_srch(el,
el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
@@ -717,7 +720,7 @@ vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_next_char(EditLine *el, int c __attribute__((__unused__)))
+vi_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
}
@@ -729,7 +732,7 @@ vi_next_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_prev_char(EditLine *el, int c __attribute__((__unused__)))
+vi_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
}
@@ -741,7 +744,7 @@ vi_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_to_next_char(EditLine *el, int c __attribute__((__unused__)))
+vi_to_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
}
@@ -753,7 +756,7 @@ vi_to_next_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_to_prev_char(EditLine *el, int c __attribute__((__unused__)))
+vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
}
@@ -765,7 +768,7 @@ vi_to_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__)))
+vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
@@ -779,7 +782,7 @@ vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__)))
+vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
el_action_t r;
int dir = el->el_search.chadir;
@@ -797,20 +800,20 @@ vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_match(EditLine *el, int c __attribute__((__unused__)))
+vi_match(EditLine *el, Int c __attribute__((__unused__)))
{
- const char match_chars[] = "()[]{}";
- char *cp;
- int delta, i, count;
- char o_ch, c_ch;
+ const Char match_chars[] = STR("()[]{}");
+ Char *cp;
+ size_t delta, i, count;
+ Char o_ch, c_ch;
*el->el_line.lastchar = '\0'; /* just in case */
- i = strcspn(el->el_line.cursor, match_chars);
+ i = Strcspn(el->el_line.cursor, match_chars);
o_ch = el->el_line.cursor[i];
if (o_ch == 0)
return CC_ERROR;
- delta = strchr(match_chars, o_ch) - match_chars;
+ delta = (size_t)(Strchr(match_chars, o_ch) - match_chars);
c_ch = match_chars[delta ^ 1];
count = 1;
delta = 1 - (delta & 1) * 2;
@@ -833,9 +836,9 @@ vi_match(EditLine *el, int c __attribute__((__unused__)))
if (delta > 0)
el->el_line.cursor++;
cv_delfini(el);
- return (CC_REFRESH);
+ return CC_REFRESH;
}
- return (CC_CURSOR);
+ return CC_CURSOR;
}
/* vi_undo_line():
@@ -844,7 +847,7 @@ vi_match(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_undo_line(EditLine *el, int c __attribute__((__unused__)))
+vi_undo_line(EditLine *el, Int c __attribute__((__unused__)))
{
cv_undo(el);
@@ -858,7 +861,7 @@ vi_undo_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_to_column(EditLine *el, int c __attribute__((__unused__)))
+vi_to_column(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
@@ -872,11 +875,11 @@ vi_to_column(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_yank_end(EditLine *el, int c __attribute__((__unused__)))
+vi_yank_end(EditLine *el, Int c __attribute__((__unused__)))
{
cv_yank(el, el->el_line.cursor,
- el->el_line.lastchar - el->el_line.cursor);
+ (int)(el->el_line.lastchar - el->el_line.cursor));
return CC_REFRESH;
}
@@ -886,7 +889,7 @@ vi_yank_end(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_yank(EditLine *el, int c __attribute__((__unused__)))
+vi_yank(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_action(el, YANK);
@@ -898,7 +901,7 @@ vi_yank(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_comment_out(EditLine *el, int c __attribute__((__unused__)))
+vi_comment_out(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
@@ -915,18 +918,19 @@ vi_comment_out(EditLine *el, int c __attribute__((__unused__)))
* this is against historical precedent...
*/
#if defined(__weak_reference) && !defined(__FreeBSD__)
-extern char *get_alias_text(const char *) __weak_reference(get_alias_text);
+__weakref_visible char *my_get_alias_text(const char *)
+ __weak_reference(get_alias_text);
#endif
protected el_action_t
/*ARGSUSED*/
vi_alias(EditLine *el __attribute__((__unused__)),
- int c __attribute__((__unused__)))
+ Int c __attribute__((__unused__)))
{
#if defined(__weak_reference) && !defined(__FreeBSD__)
char alias_name[3];
char *alias_text;
- if (get_alias_text == 0) {
+ if (my_get_alias_text == 0) {
return CC_ERROR;
}
@@ -935,9 +939,9 @@ vi_alias(EditLine *el __attribute__((__unused__)),
if (el_getc(el, &alias_name[1]) != 1)
return CC_ERROR;
- alias_text = get_alias_text(alias_name);
+ alias_text = my_get_alias_text(alias_name);
if (alias_text != NULL)
- el_push(el, alias_text);
+ FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch));
return CC_NORM;
#else
return CC_ERROR;
@@ -950,14 +954,14 @@ vi_alias(EditLine *el __attribute__((__unused__)),
*/
protected el_action_t
/*ARGSUSED*/
-vi_to_history_line(EditLine *el, int c __attribute__((__unused__)))
+vi_to_history_line(EditLine *el, Int c __attribute__((__unused__)))
{
int sv_event_no = el->el_history.eventno;
el_action_t rval;
if (el->el_history.eventno == 0) {
- (void) strncpy(el->el_history.buf, el->el_line.buffer,
+ (void) Strncpy(el->el_history.buf, el->el_line.buffer,
EL_BUFSIZ);
el->el_history.last = el->el_history.buf +
(el->el_line.lastchar - el->el_line.buffer);
@@ -995,14 +999,19 @@ vi_to_history_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_histedit(EditLine *el, int c __attribute__((__unused__)))
+vi_histedit(EditLine *el, Int c __attribute__((__unused__)))
{
int fd;
pid_t pid;
- int st;
+ ssize_t st;
+ int status;
char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
char *cp;
+ size_t len;
+ Char *line;
+ mbstate_t state;
+ memset(&state, 0, sizeof(mbstate_t));
if (el->el_state.doingarg) {
if (vi_to_history_line(el, 0) == CC_ERROR)
return CC_ERROR;
@@ -1011,16 +1020,35 @@ vi_histedit(EditLine *el, int c __attribute__((__unused__)))
fd = mkstemp(tempfile);
if (fd < 0)
return CC_ERROR;
- cp = el->el_line.buffer;
- if (write(fd, cp, el->el_line.lastchar - cp +0u) == -1)
+ len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
+#define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
+ cp = el_malloc(TMP_BUFSIZ * sizeof(*cp));
+ if (cp == NULL) {
+ unlink(tempfile);
+ close(fd);
+ return CC_ERROR;
+ }
+ line = el_malloc(len * sizeof(*line));
+ if (line == NULL) {
+ el_free(cp);
+ return CC_ERROR;
+ }
+ Strncpy(line, el->el_line.buffer, len);
+ line[len] = '\0';
+ wcsrtombs(cp, (const wchar_t **) &line, TMP_BUFSIZ - 1, &state);
+ cp[TMP_BUFSIZ - 1] = '\0';
+ len = strlen(cp);
+ if (write(fd, cp, len) == -1)
goto error;
- if (write(fd, "\n", 1) == -1)
+ if (write(fd, "\n", (size_t)1) == -1)
goto error;
pid = fork();
switch (pid) {
case -1:
close(fd);
unlink(tempfile);
+ el_free(cp);
+ el_free(line);
return CC_ERROR;
case 0:
close(fd);
@@ -1028,14 +1056,25 @@ vi_histedit(EditLine *el, int c __attribute__((__unused__)))
exit(0);
/*NOTREACHED*/
default:
- while (waitpid(pid, &st, 0) != pid)
+ while (waitpid(pid, &status, 0) != pid)
continue;
- lseek(fd, 0ll, SEEK_SET);
- st = read(fd, cp, el->el_line.limit - cp +0u);
- if (st > 0 && cp[st - 1] == '\n')
- st--;
- el->el_line.cursor = cp;
- el->el_line.lastchar = cp + st;
+ lseek(fd, (off_t)0, SEEK_SET);
+ st = read(fd, cp, TMP_BUFSIZ);
+ if (st > 0) {
+ len = (size_t)(el->el_line.lastchar -
+ el->el_line.buffer);
+ memset(&state, 0, sizeof(mbstate_t));
+ len = mbsrtowcs(el->el_line.buffer,
+ (const char**) &cp, len, &state);
+ if (len > 0 && el->el_line.buffer[len -1] == '\n')
+ --len;
+ }
+ else
+ len = 0;
+ el->el_line.cursor = el->el_line.buffer;
+ el->el_line.lastchar = el->el_line.buffer + len;
+ el_free(cp);
+ el_free(line);
break;
}
@@ -1059,34 +1098,35 @@ error:
*/
protected el_action_t
/*ARGSUSED*/
-vi_history_word(EditLine *el, int c __attribute__((__unused__)))
+vi_history_word(EditLine *el, Int c __attribute__((__unused__)))
{
- const char *wp = HIST_FIRST(el);
- const char *wep, *wsp;
+ const Char *wp = HIST_FIRST(el);
+ const Char *wep, *wsp;
int len;
- char *cp;
- const char *lim;
+ Char *cp;
+ const Char *lim;
if (wp == NULL)
return CC_ERROR;
wep = wsp = 0;
do {
- while (isspace((unsigned char)*wp))
+ while (Isspace(*wp))
wp++;
if (*wp == 0)
break;
wsp = wp;
- while (*wp && !isspace((unsigned char)*wp))
+ while (*wp && !Isspace(*wp))
wp++;
wep = wp;
- } while ((!el->el_state.doingarg || --el->el_state.argument > 0) && *wp != 0);
+ } while ((!el->el_state.doingarg || --el->el_state.argument > 0)
+ && *wp != 0);
if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0))
return CC_ERROR;
cv_undo(el);
- len = wep - wsp;
+ len = (int)(wep - wsp);
if (el->el_line.cursor < el->el_line.lastchar)
el->el_line.cursor++;
c_insert(el, len + 1);
@@ -1108,7 +1148,7 @@ vi_history_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
-vi_redo(EditLine *el, int c __attribute__((__unused__)))
+vi_redo(EditLine *el, Int c __attribute__((__unused__)))
{
c_redo_t *r = &el->el_chared.c_redo;
@@ -1124,10 +1164,10 @@ vi_redo(EditLine *el, int c __attribute__((__unused__)))
/* sanity */
r->pos = r->lim - 1;
r->pos[0] = 0;
- el_push(el, r->buf);
+ FUN(el,push)(el, r->buf);
}
el->el_state.thiscmd = r->cmd;
el->el_state.thisch = r->ch;
- return (*el->el_map.func[r->cmd])(el, r->ch);
+ return (*el->el_map.func[r->cmd])(el, r->ch);
}
diff --git a/dbug/tests.c b/dbug/tests.c
index d96388e9816..5950c5fa583 100644
--- a/dbug/tests.c
+++ b/dbug/tests.c
@@ -17,7 +17,7 @@ const char *func3()
void func2()
{
- const char *s;
+ const char *s __attribute__((unused));
DBUG_ENTER("func2");
s=func3();
DBUG_PRINT("info", ("s=%s", s));
diff --git a/extra/comp_err.c b/extra/comp_err.c
index 718b1ef7c36..1fababf3ae5 100644
--- a/extra/comp_err.c
+++ b/extra/comp_err.c
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates & Anjuta Widenius
+ 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
diff --git a/extra/innochecksum.c b/extra/innochecksum.c
index b55b510b888..ed4dfc48789 100644
--- a/extra/innochecksum.c
+++ b/extra/innochecksum.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/my_print_defaults.c b/extra/my_print_defaults.c
index d38ce1b49ff..a25381c4808 100644
--- a/extra/my_print_defaults.c
+++ b/extra/my_print_defaults.c
@@ -1,6 +1,5 @@
-
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/mysql_waitpid.c b/extra/mysql_waitpid.c
index 23177eb51cb..7777da25aa1 100644
--- a/extra/mysql_waitpid.c
+++ b/extra/mysql_waitpid.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2003, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/perror.c b/extra/perror.c
index 8621bed3e11..c8ea85c5504 100644
--- a/extra/perror.c
+++ b/extra/perror.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/replace.c b/extra/replace.c
index f09d0454eef..8aef9f9a0a0 100644
--- a/extra/replace.c
+++ b/extra/replace.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/extra/resolve_stack_dump.c b/extra/resolve_stack_dump.c
index 3422b7ef4de..dd77e1785d0 100644
--- a/extra/resolve_stack_dump.c
+++ b/extra/resolve_stack_dump.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2001, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/resolveip.c b/extra/resolveip.c
index f69aa7fec5f..871fd31482e 100644
--- a/extra/resolveip.c
+++ b/extra/resolveip.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp
index 41b03f037a7..afb492c83c5 100644
--- a/extra/yassl/src/crypto_wrapper.cpp
+++ b/extra/yassl/src/crypto_wrapper.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp
index 9f042ddbcd5..2ff30f436f5 100644
--- a/extra/yassl/src/yassl_error.cpp
+++ b/extra/yassl/src/yassl_error.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp
index 48afc86ae20..15d7ec5fb21 100644
--- a/extra/yassl/src/yassl_imp.cpp
+++ b/extra/yassl/src/yassl_imp.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp
index 66a854e6922..3d553e37337 100644
--- a/extra/yassl/src/yassl_int.cpp
+++ b/extra/yassl/src/yassl_int.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/taocrypt/include/blowfish.hpp b/extra/yassl/taocrypt/include/blowfish.hpp
index 99d932353df..e03ed41aab8 100644
--- a/extra/yassl/taocrypt/include/blowfish.hpp
+++ b/extra/yassl/taocrypt/include/blowfish.hpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp
index ad66a5bf9d0..3b9d0d9b095 100644
--- a/extra/yassl/taocrypt/include/runtime.hpp
+++ b/extra/yassl/taocrypt/include/runtime.hpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp
index a3fbd9b7d74..bf40f414eaa 100644
--- a/extra/yassl/taocrypt/src/aes.cpp
+++ b/extra/yassl/taocrypt/src/aes.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp
index 6da0040c6d9..b4afda44535 100644
--- a/extra/yassl/taocrypt/src/algebra.cpp
+++ b/extra/yassl/taocrypt/src/algebra.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/taocrypt/src/blowfish.cpp b/extra/yassl/taocrypt/src/blowfish.cpp
index 445de6d8935..2e68f7ffb5c 100644
--- a/extra/yassl/taocrypt/src/blowfish.cpp
+++ b/extra/yassl/taocrypt/src/blowfish.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/taocrypt/src/coding.cpp b/extra/yassl/taocrypt/src/coding.cpp
index 7c6a6a8bd8b..75c8f44f636 100644
--- a/extra/yassl/taocrypt/src/coding.cpp
+++ b/extra/yassl/taocrypt/src/coding.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp
index c00815df8cf..04c4cefff98 100644
--- a/extra/yassl/taocrypt/src/integer.cpp
+++ b/extra/yassl/taocrypt/src/integer.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/taocrypt/src/misc.cpp b/extra/yassl/taocrypt/src/misc.cpp
index b0382d0ba69..07ef25ad773 100644
--- a/extra/yassl/taocrypt/src/misc.cpp
+++ b/extra/yassl/taocrypt/src/misc.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/taocrypt/src/twofish.cpp b/extra/yassl/taocrypt/src/twofish.cpp
index c7f2e27d4f3..15bb778f444 100644
--- a/extra/yassl/taocrypt/src/twofish.cpp
+++ b/extra/yassl/taocrypt/src/twofish.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp
index e14cdc54ae0..a0a9fafc87e 100644
--- a/extra/yassl/testsuite/test.hpp
+++ b/extra/yassl/testsuite/test.hpp
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/heap.h b/include/heap.h
index 6ce95c88521..10b165d89c6 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 2a7175f739a..00f02edc620 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/m_string.h b/include/m_string.h
index 6268888028f..7c95c7319dc 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -58,14 +58,16 @@
/* Unixware 7 */
#if !defined(HAVE_BFILL)
# define bfill(A,B,C) memset((A),(C),(B))
-# define bmove_align(A,B,C) memcpy((A),(B),(C))
#endif
+# define bmove_align(A,B,C) memcpy((A),(B),(C))
+
#if !defined(HAVE_BCMP)
-# define bcopy(s, d, n) memcpy((d), (s), (n))
# define bcmp(A,B,C) memcmp((A),(B),(C))
-# define bzero(A,B) memset((A),0,(B))
-# define bmove_align(A,B,C) memcpy((A),(B),(C))
+#endif
+
+#if !defined(bzero) && (!defined(HAVE_BZERO) || !defined(HAVE_DECL_BZERO))
+# define bzero(A,B) memset((A),0,(B))
#endif
#if defined(__cplusplus)
diff --git a/include/maria.h b/include/maria.h
index 3ee5b6b9df8..404ce98dafd 100644
--- a/include/maria.h
+++ b/include/maria.h
@@ -336,6 +336,8 @@ extern void maria_enable_logging(MARIA_HA *info);
#define HA_RECOVER_FORCE 4 /* Recover even if we loose rows */
#define HA_RECOVER_QUICK 8 /* Don't check rows in data file */
+#define HA_RECOVER_ANY (HA_RECOVER_DEFAULT | HA_RECOVER_BACKUP | HA_RECOVER_FORCE | HA_RECOVER_QUICK)
+
/* this is used to pass to mysql_mariachk_table */
#define MARIA_CHK_REPAIR 1 /* equivalent to mariachk -r */
diff --git a/include/my_alarm.h b/include/my_alarm.h
index 57d86f56755..c3707cba395 100644
--- a/include/my_alarm.h
+++ b/include/my_alarm.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/my_bitmap.h b/include/my_bitmap.h
index 7b78252ea27..a6cd874255a 100644
--- a/include/my_bitmap.h
+++ b/include/my_bitmap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+/* Copyright (c) 2001, 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
diff --git a/include/my_dbug.h b/include/my_dbug.h
index fb5838e8b5c..88bbc3f968f 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
- Copyright (c) 2009-2011 Monty Program Ab
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ Copyright (C) 2000-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
diff --git a/include/my_decimal_limits.h b/include/my_decimal_limits.h
index b395a2ed144..50d70357c42 100644
--- a/include/my_decimal_limits.h
+++ b/include/my_decimal_limits.h
@@ -38,7 +38,7 @@
/**
maximum length of string representation (number of maximum decimal
- digits + 1 position for sign + 1 position for decimal point)
+ digits + 1 position for sign + 1 position for decimal point, no terminator)
*/
#define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2)
diff --git a/include/my_getopt.h b/include/my_getopt.h
index 092accc05a1..61c4b054615 100644
--- a/include/my_getopt.h
+++ b/include/my_getopt.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/my_global.h b/include/my_global.h
index 451cb9127a3..8d54448f477 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2001, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -45,6 +45,8 @@
#undef __WIN__
#undef __WIN32__
#define HAVE_ERRNO_AS_DEFINE
+#define _POSIX_MONOTONIC_CLOCK
+#define _POSIX_THREAD_CPUTIME
#endif /* __CYGWIN__ */
/* to make command line shorter we'll define USE_PRAGMA_INTERFACE here */
@@ -1386,21 +1388,10 @@ do { doubleget_union _tmp; \
#define NO_EMBEDDED_ACCESS_CHECKS
#endif
-#if defined(_WIN32)
+#ifdef _WIN32
#define dlsym(lib, name) (void*)GetProcAddress((HMODULE)lib, name)
#define dlopen(libname, unused) LoadLibraryEx(libname, NULL, 0)
#define dlclose(lib) FreeLibrary((HMODULE)lib)
-#ifndef HAVE_DLOPEN
-#define HAVE_DLOPEN
-#endif
-#endif
-
-#if defined(HAVE_DLFCN_H)
-#include <dlfcn.h>
-#endif
-
-#ifndef HAVE_DLERROR
-#ifdef _WIN32
static inline char *dlerror(void)
{
static char win_errormsg[2048];
@@ -1409,9 +1400,23 @@ static inline char *dlerror(void)
return win_errormsg;
return "";
}
+#define HAVE_DLOPEN 1
+#define HAVE_DLERROR 1
+#endif
+
+#ifdef HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#ifdef HAVE_DLOPEN
+#ifndef HAVE_DLERROR
+#define dlerror() ""
+#endif
#else
#define dlerror() "No support for dynamic loading (static build?)"
-#endif
+#define dlopen(A,B) 0
+#define dlsym(A,B) 0
+#define dlclose(A) 0
#endif
/*
diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h
index a9590a76368..41440fb2c74 100644
--- a/include/my_stacktrace.h
+++ b/include/my_stacktrace.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2001, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/my_time.h b/include/my_time.h
index 668b57fc052..9bd545bb850 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2004, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/myisam.h b/include/myisam.h
index 0aa8fe79c27..3d4eecb7cbe 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/mysql.h b/include/mysql.h
index d06db7ed25d..fb99242132b 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index 556ba91c7b9..9592ec7b046 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -140,6 +140,7 @@ void get_salt_from_password(unsigned char *res, const char *password);
void make_password_from_salt(char *to, const unsigned char *hash_stage2);
char *octet2hex(char *to, const char *str, unsigned int len);
char *get_tty_password(const char *opt_message);
+void get_tty_password_buff(const char *opt_message, char *to, size_t length);
const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
my_bool my_thread_init(void);
void my_thread_end(void);
diff --git a/include/mysql/client_plugin.h b/include/mysql/client_plugin.h
index 35b415fdaf0..b2df0019dfe 100644
--- a/include/mysql/client_plugin.h
+++ b/include/mysql/client_plugin.h
@@ -30,22 +30,19 @@
unlike other compilers, uses C++ mangling for variables not only
for functions.
*/
+#undef MYSQL_PLUGIN_EXPORT
#if defined(_MSC_VER)
-#if defined(MYSQL_DYNAMIC_PLUGIN)
#ifdef __cplusplus
#define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
#else
#define MYSQL_PLUGIN_EXPORT __declspec(dllexport)
#endif
-#else /* MYSQL_DYNAMIC_PLUGIN */
+#else /*_MSC_VER */
#ifdef __cplusplus
#define MYSQL_PLUGIN_EXPORT extern "C"
#else
#define MYSQL_PLUGIN_EXPORT
#endif
-#endif /*MYSQL_DYNAMIC_PLUGIN */
-#else /*_MSC_VER */
-#define MYSQL_PLUGIN_EXPORT
#endif
#ifndef MYSQL_ABI_CHECK
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index 4f70fe45d43..32c971bb99e 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+/* 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
@@ -24,21 +24,17 @@
for functions.
*/
#if defined(_MSC_VER)
-#if defined(MYSQL_DYNAMIC_PLUGIN)
#ifdef __cplusplus
#define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
#else
#define MYSQL_PLUGIN_EXPORT __declspec(dllexport)
#endif
-#else /* MYSQL_DYNAMIC_PLUGIN */
+#else /*_MSC_VER */
#ifdef __cplusplus
- #define MYSQL_PLUGIN_EXPORT extern "C"
+ #define MYSQL_PLUGIN_EXPORT extern "C"
#else
- #define MYSQL_PLUGIN_EXPORT
+ #define MYSQL_PLUGIN_EXPORT
#endif
-#endif /*MYSQL_DYNAMIC_PLUGIN */
-#else /*_MSC_VER */
-#define MYSQL_PLUGIN_EXPORT
#endif
#ifdef __cplusplus
@@ -122,20 +118,26 @@ int PSIZE= sizeof(struct st_mysql_plugin); \
struct st_mysql_plugin DECLS[]= {
#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
-MYSQL_PLUGIN_EXPORT int VERSION= MARIA_PLUGIN_INTERFACE_VERSION; \
-MYSQL_PLUGIN_EXPORT int PSIZE= sizeof(struct st_maria_plugin); \
-MYSQL_PLUGIN_EXPORT struct st_maria_plugin DECLS[]= {
+int VERSION= MARIA_PLUGIN_INTERFACE_VERSION; \
+int PSIZE= sizeof(struct st_maria_plugin); \
+struct st_maria_plugin DECLS[]= {
#else
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
-MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
-MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
-MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]= {
-
-#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
-MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
-MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
-MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]= {
+MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_; \
+int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int _mysql_sizeof_struct_st_plugin_; \
+int _mysql_sizeof_struct_st_plugin_= sizeof(struct st_mysql_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_mysql_plugin _mysql_plugin_declarations_[]; \
+struct st_mysql_plugin _mysql_plugin_declarations_[]= {
+
+#define MARIA_DECLARE_PLUGIN__(NAME, VERSION, PSIZE, DECLS) \
+MYSQL_PLUGIN_EXPORT int _maria_plugin_interface_version_; \
+int _maria_plugin_interface_version_= MARIA_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int _maria_sizeof_struct_st_plugin_; \
+int _maria_sizeof_struct_st_plugin_= sizeof(struct st_maria_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_maria_plugin _maria_plugin_declarations_[]; \
+struct st_maria_plugin _maria_plugin_declarations_[]= {
#endif
diff --git a/include/mysql_com.h b/include/mysql_com.h
index adba1ba141a..171b5eb0463 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -560,6 +560,7 @@ char *octet2hex(char *to, const char *str, unsigned int len);
/* end of password.c */
char *get_tty_password(const char *opt_message);
+void get_tty_password_buff(const char *opt_message, char *to, size_t length);
const char *mysql_errno_to_sqlstate(unsigned int mysql_errno);
/* Some other useful functions */
diff --git a/include/mysql_embed.h b/include/mysql_embed.h
index b96083d07db..12b18ff965e 100644
--- a/include/mysql_embed.h
+++ b/include/mysql_embed.h
@@ -1,7 +1,8 @@
#ifndef MYSQL_EMBED_INCLUDED
#define MYSQL_EMBED_INCLUDED
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/mysys_err.h b/include/mysys_err.h
index 42c1bf3175a..f173ccd7a83 100644
--- a/include/mysys_err.h
+++ b/include/mysys_err.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h
index db99d1dfa26..81d03e54016 100644
--- a/include/sslopt-longopts.h
+++ b/include/sslopt-longopts.h
@@ -1,7 +1,8 @@
#ifndef SSLOPT_LONGOPTS_INCLUDED
#define SSLOPT_LONGOPTS_INCLUDED
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/include/welcome_copyright_notice.h b/include/welcome_copyright_notice.h
index 26c2bb2b097..9e40c17efca 100644
--- a/include/welcome_copyright_notice.h
+++ b/include/welcome_copyright_notice.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -21,10 +21,6 @@
program on start, or on help screen.
*/
#define ORACLE_WELCOME_COPYRIGHT_NOTICE(years) \
- "Copyright (c) " years ", Oracle and/or its affiliates.\n" \
- "2009-2011 Monty Program Ab\n" \
- "\n" \
- "This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n" \
- "and you are welcome to modify and redistribute it under the GPL license\n"
+ "Copyright (c) " years ", Oracle, Monty Program Ab and others.\n"
#endif /* _welcome_copyright_notice_h_ */
diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
index 9826c2d62f9..a469f243f7a 100644
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2011, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/libmysql/get_password.c b/libmysql/get_password.c
index 55b7bf41cee..dc1a29f7935 100644
--- a/libmysql/get_password.c
+++ b/libmysql/get_password.c
@@ -64,12 +64,10 @@
#if defined(__WIN__)
/* were just going to fake it here and get input from the keyboard */
-char *get_tty_password(const char *opt_message)
+void get_tty_password_buff(const char *opt_message, char *to, size_t length)
{
- char to[80];
- char *pos=to,*end=to+sizeof(to)-1;
+ char *pos=to,*end=to+length-1;
int i=0;
- DBUG_ENTER("get_tty_password");
_cputs(opt_message ? opt_message : "Enter password: ");
for (;;)
{
@@ -95,7 +93,6 @@ char *get_tty_password(const char *opt_message)
pos--; /* Allow dummy space at end */
*pos=0;
_cputs("\n");
- DBUG_RETURN(my_strdup(to,MYF(MY_FAE)));
}
#else
@@ -148,22 +145,19 @@ static void get_password(char *to,uint length,int fd, my_bool echo)
#endif /* ! HAVE_GETPASS */
-char *get_tty_password(const char *opt_message)
+void get_tty_password_buff(const char *opt_message, char *buff, size_t buflen)
{
#ifdef HAVE_GETPASS
char *passbuff;
#else /* ! HAVE_GETPASS */
TERMIO org,tmp;
#endif /* HAVE_GETPASS */
- char buff[80];
-
- DBUG_ENTER("get_tty_password");
#ifdef HAVE_GETPASS
passbuff = getpass(opt_message ? opt_message : "Enter password: ");
/* copy the password to buff and clear original (static) buffer */
- strnmov(buff, passbuff, sizeof(buff) - 1);
+ strnmov(buff, passbuff, buflen - 1);
#ifdef _PASSWORD_LEN
memset(passbuff, 0, _PASSWORD_LEN);
#endif
@@ -180,7 +174,7 @@ char *get_tty_password(const char *opt_message)
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME] = 0;
tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
- get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout)));
+ get_password(buff, buflen, fileno(stdin), isatty(fileno(stdout)));
tcsetattr(fileno(stdin), TCSADRAIN, &org);
#elif defined(HAVE_TERMIO_H)
ioctl(fileno(stdin), (int) TCGETA, &org);
@@ -189,7 +183,7 @@ char *get_tty_password(const char *opt_message)
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME]= 0;
ioctl(fileno(stdin),(int) TCSETA, &tmp);
- get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
+ get_password(buff,buflen-1,fileno(stdin),isatty(fileno(stdout)));
ioctl(fileno(stdin),(int) TCSETA, &org);
#else
gtty(fileno(stdin), &org);
@@ -197,13 +191,20 @@ char *get_tty_password(const char *opt_message)
tmp.sg_flags &= ~ECHO;
tmp.sg_flags |= RAW;
stty(fileno(stdin), &tmp);
- get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
+ get_password(buff,buflen-1,fileno(stdin),isatty(fileno(stdout)));
stty(fileno(stdin), &org);
#endif
if (isatty(fileno(stdout)))
fputc('\n',stdout);
#endif /* HAVE_GETPASS */
-
- DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
}
#endif /*__WIN__*/
+
+#ifndef MYSQL_DYNAMIC_PLUGIN
+char *get_tty_password(const char *opt_message)
+{
+ char buff[80];
+ get_tty_password_buff(opt_message, buff, sizeof(buff));
+ return my_strdup(buff, MYF(MY_FAE));
+}
+#endif
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 1294bb0062b..230376bc3b0 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index 6eb62b953a3..74fa313e576 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2010, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/man/mysql-stress-test.pl.1 b/man/mysql-stress-test.pl.1
index d8350d2ffb0..78ba75847ad 100644
--- a/man/mysql-stress-test.pl.1
+++ b/man/mysql-stress-test.pl.1
@@ -489,7 +489,7 @@ Verbose mode\&. Print more information about what the program does\&.
.SH "COPYRIGHT"
.br
.PP
-Copyright \(co 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+Copyright \(co 2007, 2010, Oracle and/or its affiliates
.PP
This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
.PP
diff --git a/man/mysql-test-run.pl.1 b/man/mysql-test-run.pl.1
index b9c3fcb6421..ebf17746b68 100644
--- a/man/mysql-test-run.pl.1
+++ b/man/mysql-test-run.pl.1
@@ -2052,7 +2052,7 @@ in their name\&.
.SH "COPYRIGHT"
.br
.PP
-Copyright \(co 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+Copyright \(co 2007, 2010, Oracle and/or its affiliates
.PP
This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
.PP
diff --git a/man/mysql_client_test.1 b/man/mysql_client_test.1
index 836670b7d8e..a366092012c 100644
--- a/man/mysql_client_test.1
+++ b/man/mysql_client_test.1
@@ -326,7 +326,7 @@ mysql\-test/var\&.
.SH "COPYRIGHT"
.br
.PP
-Copyright \(co 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+Copyright \(co 2007, 2010, Oracle and/or its affiliates
.PP
This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
.PP
diff --git a/man/mysqltest.1 b/man/mysqltest.1
index a10ac08ed68..c68d851cbfc 100644
--- a/man/mysqltest.1
+++ b/man/mysqltest.1
@@ -829,7 +829,7 @@ statement is wrapped inside a view\&. This option was added in MySQL 5\&.0\&.19\
.SH "COPYRIGHT"
.br
.PP
-Copyright \(co 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+Copyright \(co 2007, 2010, Oracle and/or its affiliates
.PP
This documentation is free software; you can redistribute it and/or modify it only under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License.
.PP
diff --git a/mysql-test/include/common-tests.inc b/mysql-test/include/common-tests.inc
index 2273d7d688d..4b61826c347 100644
--- a/mysql-test/include/common-tests.inc
+++ b/mysql-test/include/common-tests.inc
@@ -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/default_mysqld.cnf b/mysql-test/include/default_mysqld.cnf
index c3ac934f7b3..4eb758ce520 100644
--- a/mysql-test/include/default_mysqld.cnf
+++ b/mysql-test/include/default_mysqld.cnf
@@ -1,4 +1,4 @@
-# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/mysql-test/include/gis_keys.inc b/mysql-test/include/gis_keys.inc
index ad00c7e1ef9..cc8ec68f7d1 100644
--- a/mysql-test/include/gis_keys.inc
+++ b/mysql-test/include/gis_keys.inc
@@ -33,6 +33,7 @@ EXPLAIN
SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)');
SELECT COUNT(*) FROM t1 WHERE p=POINTFROMTEXT('POINT(1 2)');
+--replace_column 9 #
EXPLAIN
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
diff --git a/mysql-test/include/have_plugin_auth.inc b/mysql-test/include/have_plugin_auth.inc
index 44ff4c2520d..daa5f5114e8 100644
--- a/mysql-test/include/have_plugin_auth.inc
+++ b/mysql-test/include/have_plugin_auth.inc
@@ -1,5 +1,4 @@
-disable_query_log;
---require r/true.require
-select (PLUGIN_LIBRARY LIKE 'auth_test_plugin%') as `TRUE` FROM INFORMATION_SCHEMA.PLUGINS
- WHERE PLUGIN_NAME='test_plugin_server';
-enable_query_log;
+if (`select count(*) = 0 from information_schema.plugins where plugin_name = 'test_plugin_server' and plugin_status='active'`)
+{
+ --skip Needs auth_test_plugin
+}
diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc
index ea4fc6439d2..e77cb220375 100644
--- a/mysql-test/include/icp_tests.inc
+++ b/mysql-test/include/icp_tests.inc
@@ -438,6 +438,7 @@ LIMIT 1;
DROP TABLE t1;
--echo #
+--echo #
--echo # Bug#59259 "Incorrect rows returned for a correlated subquery
--echo # when ICP is on"
--echo #
@@ -744,3 +745,110 @@ 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;
+
diff --git a/mysql-test/include/index_merge1.inc b/mysql-test/include/index_merge1.inc
index 86298f86906..88dd4c31910 100644
--- a/mysql-test/include/index_merge1.inc
+++ b/mysql-test/include/index_merge1.inc
@@ -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;
diff --git a/mysql-test/include/mix1.inc b/mysql-test/include/mix1.inc
index 588de7b9f6a..87d6698865a 100644
--- a/mysql-test/include/mix1.inc
+++ b/mysql-test/include/mix1.inc
@@ -1188,9 +1188,9 @@ DROP TABLE t1;
create table t1 (a bit(1) not null,b int) engine=myisam;
create table t2 (c int) engine=innodb;
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=off';
+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;
diff --git a/mysql-test/include/mtr_check.sql b/mysql-test/include/mtr_check.sql
index c9708f988de..939a3215fd5 100644
--- a/mysql-test/include/mtr_check.sql
+++ b/mysql-test/include/mtr_check.sql
@@ -1,4 +1,4 @@
--- Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+-- Copyright (c) 2008, 2010, Oracle and/or its affiliates
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
@@ -29,7 +29,8 @@ BEGIN
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
WHERE variable_name NOT IN ('timestamp', 'innodb_file_format_max')
AND variable_name not like "Last_IO_Err*"
- ORDER BY VARIABLE_NAME;
+ AND variable_name != 'INNODB_IBUF_MAX_SIZE'
+ ORDER BY variable_name;
-- Dump all databases, there should be none
-- except those that was created during bootstrap
diff --git a/mysql-test/include/mtr_warnings.sql b/mysql-test/include/mtr_warnings.sql
index ce1563fc993..1248e72f3b9 100644
--- a/mysql-test/include/mtr_warnings.sql
+++ b/mysql-test/include/mtr_warnings.sql
@@ -1,4 +1,4 @@
--- Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+-- Copyright (c) 2008, 2011, Oracle and/or its affiliates
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
diff --git a/mysql-test/lib/My/Config.pm b/mysql-test/lib/My/Config.pm
index 23f29b53ff3..1823ed59e02 100644
--- a/mysql-test/lib/My/Config.pm
+++ b/mysql-test/lib/My/Config.pm
@@ -1,6 +1,6 @@
# -*- cperl -*-
-# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/mysql-test/lib/My/ConfigFactory.pm b/mysql-test/lib/My/ConfigFactory.pm
index 1bc9977cf4a..73bad5bd81d 100644
--- a/mysql-test/lib/My/ConfigFactory.pm
+++ b/mysql-test/lib/My/ConfigFactory.pm
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2011, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
diff --git a/mysql-test/lib/My/Options.pm b/mysql-test/lib/My/Options.pm
index 55d1010aad8..ff3992ecb2e 100644
--- a/mysql-test/lib/My/Options.pm
+++ b/mysql-test/lib/My/Options.pm
@@ -150,7 +150,7 @@ sub is_set {
foreach my $set_opt (@$set_opts){
my ($opt_name2, $value2)= _split_option($set_opt);
- if ($opt_name1 eq $opt_name2){
+ if ($opt_name1 eq $opt_name2 and $value1 eq $value2){
# Option already set
return 1;
}
diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc
index 2f90b65f62e..ffe11417e7d 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process.cc
+++ b/mysql-test/lib/My/SafeProcess/safe_process.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysql-test/lib/My/SafeProcess/safe_process.pl b/mysql-test/lib/My/SafeProcess/safe_process.pl
index 1b3c0aa9a5f..de844e010a1 100644
--- a/mysql-test/lib/My/SafeProcess/safe_process.pl
+++ b/mysql-test/lib/My/SafeProcess/safe_process.pl
@@ -1,7 +1,7 @@
#!/usr/bin/perl
# -*- cperl -*-
-# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2011, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/mysql-test/lib/My/Test.pm b/mysql-test/lib/My/Test.pm
index 5b202ea17a1..04dccfdaa4a 100644
--- a/mysql-test/lib/My/Test.pm
+++ b/mysql-test/lib/My/Test.pm
@@ -97,7 +97,8 @@ sub read_test {
chomp($serialized);
$serialized =~ s/\\([0-9a-fA-F]{2})/chr(hex($1))/eg;
my $test= Storable::thaw($serialized);
- die "wrong class (hack attempt?): ".ref($test)
+ use Data::Dumper;
+ die "wrong class (hack attempt?): ".ref($test)."\n".Dumper(\$test)
unless ref($test) eq 'My::Test';
resfile_from_test($test) if $::opt_resfile;
return $test;
diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
index 2d8f111f054..3c8d3059713 100644
--- a/mysql-test/lib/mtr_cases.pm
+++ b/mysql-test/lib/mtr_cases.pm
@@ -470,20 +470,32 @@ sub collect_one_suite
#print_testcases(@cases);
my @new_cases;
- foreach my $comb (@combinations)
+ TEST: foreach my $test (@cases)
{
- foreach my $test (@cases)
- {
-
- next if ( $test->{'skip'} );
+ if ( $test->{'skip'} )
+ {
+ push(@new_cases, $test);
+ next;
+ }
- # Skip this combination if the values it provides
- # already are set in master_opt or slave_opt
+ foreach my $comb (@combinations)
+ {
+ # Skip all other combinations if the values they change
+ # are already fixed in master_opt or slave_opt
if (My::Options::is_set($test->{master_opt}, $comb->{comb_opt}) &&
My::Options::is_set($test->{slave_opt}, $comb->{comb_opt}) ){
- next;
+
+ # Add combination name short name
+ $test->{combination}= $comb->{name};
+
+ # Add the test to new test cases list
+ push(@new_cases, $test);
+ next TEST;
}
+ }
+ foreach my $comb (@combinations)
+ {
# Copy test options
my $new_test= My::Test->new();
while (my ($key, $value) = each(%$test)) {
@@ -506,17 +518,6 @@ sub collect_one_suite
}
}
- # Add the plain test if it was not already added
- # as part of a combination
- my %added;
- foreach my $new_test (@new_cases){
- $added{$new_test->{name}}= 1;
- }
- foreach my $test (@cases){
- push(@new_cases, $test) unless $added{$test->{name}};
- }
-
-
#print_testcases(@new_cases);
@cases= @new_cases;
#print_testcases(@cases);
@@ -643,9 +644,6 @@ sub process_opts {
my @opts= @{$tinfo->{$opt_name}};
$tinfo->{$opt_name} = [];
- my @plugins;
- my %seen;
-
foreach my $opt (@opts)
{
my $value;
@@ -661,14 +659,6 @@ sub process_opts {
next;
}
- $value= mtr_match_prefix($opt, "--plugin-load=");
- if (defined $value)
- {
- push @plugins, $value unless $seen{$value};
- $seen{$value}=1;
- next;
- }
-
$value= mtr_match_prefix($opt, "--result-file=");
if ( defined $value )
{
@@ -715,11 +705,6 @@ sub process_opts {
# Ok, this was a real option, add it
push(@{$tinfo->{$opt_name}}, $opt);
}
-
- if (@plugins) {
- my $sep = (IS_WINDOWS) ? ';' : ':';
- push @{$tinfo->{$opt_name}}, "--plugin-load=" . join($sep, @plugins);
- }
}
diff --git a/mysql-test/lib/mtr_gprof.pl b/mysql-test/lib/mtr_gprof.pl
index 15aad17a3d4..34e722a251f 100644
--- a/mysql-test/lib/mtr_gprof.pl
+++ b/mysql-test/lib/mtr_gprof.pl
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2011, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index cebb895da6e..4bb6be711f0 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -1,5 +1,5 @@
# -*- cperl -*-
-# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2010, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -130,7 +130,7 @@ sub sleep_until_file_created ($$$$) {
mtr_debug("Sleep $sleeptime milliseconds waiting for $pidfile");
# Print extra message every $warn_seconds seconds
- if ( $seconds > 1 && $seconds % $warn_seconds == 0 && $seconds < $timeout )
+ if ( $seconds > 1 && ($seconds*10) % ($warn_seconds*10) == 0 && $seconds < $timeout )
{
my $left= $timeout - $seconds;
mtr_warning("Waited $seconds seconds for $pidfile to be created, " .
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 2ec52f952ab..ba6e79c98d8 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -176,6 +176,7 @@ my $DEFAULT_SUITES= join(',', qw(
pbxt
percona
perfschema
+ plugins
rpl
sphinx
sys_vars
@@ -2845,7 +2846,7 @@ sub check_debug_support ($) {
#
# Helper function to find the correct value for the opt_vs_config
# if it was not set explicitly.
-#
+#
# the configuration with the most recent build dir in sql/ is selected.
#
# note: looking for all BuildLog.htm files everywhere in the tree with the
@@ -2874,6 +2875,33 @@ sub fix_vs_config_dir () {
}
+#
+# Helper function to handle configuration-based subdirectories which Visual
+# Studio uses for storing binaries. If opt_vs_config is set, this returns
+# a path based on that setting; if not, it returns paths for the default
+# /release/ and /debug/ subdirectories.
+#
+# $exe can be undefined, if the directory itself will be used
+#
+sub vs_config_dirs ($$) {
+ my ($path_part, $exe) = @_;
+
+ $exe = "" if not defined $exe;
+
+ # Don't look in these dirs when not on windows
+ return () unless IS_WINDOWS;
+
+ if ($opt_vs_config)
+ {
+ return ("$basedir/$path_part/$opt_vs_config/$exe");
+ }
+
+ return ("$basedir/$path_part/release/$exe",
+ "$basedir/$path_part/relwithdebinfo/$exe",
+ "$basedir/$path_part/debug/$exe");
+}
+
+
sub check_ndbcluster_support ($) {
my $mysqld_variables= shift;
@@ -4134,7 +4162,7 @@ sub run_testcase ($$) {
# Allow only alpanumerics pluss _ - + . in combination names,
# or anything beginning with -- (the latter comes from --combination)
my $combination= $tinfo->{combination};
- if ($combination && $combination !~ /^\w[-\w\.\+]+$/
+ if ($combination && $combination !~ /^\w[-\w\.\+]*$/
&& $combination !~ /^--/)
{
mtr_error("Combination '$combination' contains illegal characters");
@@ -5301,6 +5329,9 @@ sub mysqld_arguments ($$$) {
}
my $found_skip_core= 0;
+ my @plugins;
+ my %seen;
+ my $plugin;
foreach my $arg ( @$extra_opts )
{
# Skip --defaults-file option since it's handled above.
@@ -5320,10 +5351,10 @@ sub mysqld_arguments ($$$) {
{
; # Dont add --skip-log-bin when mysqld have --log-slave-updates in config
}
- elsif ($arg eq "")
+ elsif ($plugin = mtr_match_prefix($arg, "--plugin-load="))
{
- # We can get an empty argument when we set environment variables to ""
- # (e.g plugin not found). Just skip it.
+ push @plugins, $plugin unless $seen{$plugin};
+ $seen{$plugin} = 1;
}
else
{
@@ -5341,6 +5372,11 @@ sub mysqld_arguments ($$$) {
mtr_add_arg($args, "--loose-debug-sync-timeout=%s",
$opt_debug_sync_timeout) unless $opt_user_args;
+ if (@plugins) {
+ my $sep = (IS_WINDOWS) ? ';' : ':';
+ mtr_add_arg($args, "--plugin-load=%s" . join($sep, @plugins));
+ }
+
return $args;
}
@@ -5441,8 +5477,8 @@ 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.",
"See trace file $trace_name.\n");
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index c67318ff74e..d66940add5d 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -12738,8 +12738,15 @@ INSERT INTO t1 (col1, col2) VALUES (1, "value");
ERROR HY000: Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
REPAIR TABLE t1;
Table Op Msg_type Msg_text
-test.t1 repair Error Table upgrade required. Please do "REPAIR TABLE `t1`" or dump/reload to fix it!
-test.t1 repair status Table is already up to date
+test.t1 repair status OK
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `col1` int(11) DEFAULT NULL,
+ `col2` varchar(20) DEFAULT NULL
+) ENGINE=ARCHIVE DEFAULT CHARSET=latin1
+SELECT * FROM t1;
+col1 col2
DROP TABLE t1;
#
# BUG#48757 - missing .ARZ file causes server crash
diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result
index f5f287fea88..a1eba2701f3 100644
--- a/mysql-test/r/cast.result
+++ b/mysql-test/r/cast.result
@@ -714,12 +714,17 @@ Warnings:
Warning 1708 The value of 'max_allowed_packet' should be no less than the value of 'net_buffer_length'
SELECT CONVERT('a', BINARY(2049));
CONVERT('a', BINARY(2049))
-NULL
+a
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
+a
+Warnings:
+Warning 1301 Result of cast_as_char() was larger than max_allowed_packet (2048) - truncated
+SELECT length(CONVERT(repeat('a',2048), CHAR(2049)));
+length(CONVERT(repeat('a',2048), CHAR(2049)))
+2048
Warnings:
Warning 1301 Result of cast_as_char() was larger than max_allowed_packet (2048) - truncated
SET @@GLOBAL.max_allowed_packet=default;
diff --git a/mysql-test/r/compress.result b/mysql-test/r/compress.result
index 439ac7ce90a..ff99f1da32f 100644
--- a/mysql-test/r/compress.result
+++ b/mysql-test/r/compress.result
@@ -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
@@ -1428,6 +1430,7 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+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
diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result
index bd5da049523..67d41de4af4 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 cd97c898e18..c6b8bf73a6f 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
@@ -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 9 Using where
+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 9 Using where
+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;
@@ -205,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;
@@ -429,7 +432,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 4 Using join buffer (flat, BNL join)
3 DERIVED t1 ALL NULL NULL NULL NULL 2
-3 DERIVED t3 ALL NULL NULL NULL NULL 2 Using where
+3 DERIVED t3 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
4 SUBQUERY t1 ALL NULL NULL NULL NULL 2
2 SUBQUERY <derived5> ALL NULL NULL NULL NULL 2
5 DERIVED t2 index NULL b 5 NULL 2 Using index
@@ -437,3 +440,4 @@ SELECT 1 FROM t1 JOIN v1 ON 1 > (SELECT 1 FROM v2);
ERROR 21000: Subquery returns more than 1 row
DROP TABLE t1, t2;
DROP VIEW v1, v2;
+set optimizer_switch=@save_derived_optimizer_switch;
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index 591aaded9f1..587a1dd9e31 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -1,8 +1,10 @@
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);
@@ -1482,6 +1484,8 @@ 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
@@ -1489,8 +1493,8 @@ WHERE t3.b IN (SELECT v1.b FROM v1, t2
WHERE t2.c = v1.c AND t2.c = v1.b AND v1.b = t3.c);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 system NULL NULL NULL NULL 1
-1 PRIMARY t3 ALL NULL NULL NULL NULL 2 Using where; Start temporary
-1 PRIMARY <derived3> ALL NULL NULL NULL NULL 3 Using where; End temporary
+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
@@ -1512,6 +1516,7 @@ 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;
#
@@ -1597,6 +1602,7 @@ 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 (
@@ -1612,30 +1618,36 @@ SET SESSION join_buffer_size = 512;
EXPLAIN
SELECT t2.d FROM t1,t2,v3 WHERE v3.e = t2.d AND v3.i < 3;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ALL NULL NULL NULL NULL 3
-1 SIMPLE t3 ref e e 3 test.t2.d 1 Using index
-1 SIMPLE t5 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join)
+1 SIMPLE 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
-d
-e
w
-d
-e
w
-d
-e
w
-d
-e
w
-d
-e
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;
@@ -1649,6 +1661,8 @@ 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
@@ -1710,6 +1724,7 @@ 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
@@ -1719,6 +1734,8 @@ 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
@@ -1749,6 +1766,7 @@ a b
5 r
9 y
SET SESSION join_cache_level = default;
+SET optimizer_switch=@save_optimizer_switch;
DROP VIEW v2;
DROP TABLE t1,t2,t3;
#
@@ -1872,3 +1890,4 @@ col_varchar_key pk col_varchar_key col_varchar_nokey
set max_heap_table_size= @tmp_882994;
drop table t1,t2,t3;
set optimizer_switch=@exit_optimizer_switch;
+set join_cache_level=@exit_join_cache_level;
diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result
index 3dce43c8bef..75f054ecbbe 100644
--- a/mysql-test/r/distinct.result
+++ b/mysql-test/r/distinct.result
@@ -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
@@ -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;
diff --git a/mysql-test/r/endspace.result b/mysql-test/r/endspace.result
index 4eca88774b4..f9619db7e64 100644
--- a/mysql-test/r/endspace.result
+++ b/mysql-test/r/endspace.result
@@ -203,13 +203,13 @@ teststring
teststring
select text1, length(text1) from t1 where text1='teststring' or text1 like 'teststring_%';
text1 length(text1)
-teststring 10
teststring 11
+teststring 10
teststring 11
select text1, length(text1) from t1 where text1='teststring' or text1 >= 'teststring\t';
text1 length(text1)
-teststring 10
teststring 11
+teststring 10
teststring 11
select concat('|', text1, '|') from t1 order by text1;
concat('|', text1, '|')
diff --git a/mysql-test/r/error_simulation.result b/mysql-test/r/error_simulation.result
index ae47527145a..b3fbc433247 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_dbug= '+d,only_one_Unique_may_be_created';
EXPLAIN
SELECT * FROM t1 LEFT JOIN t2 ON ( t2.a < 10 OR t2.b < 10 );
@@ -81,7 +83,20 @@ a a b filler
8 1 1 data
9 1 1 data
SET SESSION debug_dbug= DEFAULT;
+SET optimizer_switch=@save_optimizer_switch;
DROP TABLE t1, t2;
#
+# Bug#11747970 34660: CRASH WHEN FEDERATED TABLE LOSES CONNECTION DURING INSERT ... SELECT
+#
+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_dbug="+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);
+ERROR HY000: Unknown error
+SET SESSION debug_dbug = DEFAULT;
+DROP TABLE t1,t2;
+#
# End of 5.1 tests
#
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index 36aefafa8e2..a6fa21ad800 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -193,24 +193,27 @@ 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; Start temporary
-1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; End temporary
+1 PRIMARY OUTR 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
flush tables;
EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN ( SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.t < '2005-11-13 7:41:31' );
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where; Start temporary
-1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; End temporary
+1 PRIMARY OUTR 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
@@ -279,7 +282,7 @@ 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
@@ -287,7 +290,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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;
@@ -303,7 +306,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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;
@@ -339,6 +342,8 @@ DROP TABLE t1;
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
@@ -346,4 +351,5 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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` where 0) `t`
+set optimizer_switch=@tmp_optimizer_switch;
DROP TABLE t1,t2;
diff --git a/mysql-test/r/foreign_key.result b/mysql-test/r/foreign_key.result
index 5c228b6241b..a82151ddec0 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 c067ff02574..0f50f913ab3 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -692,10 +692,8 @@ PREPARE stmt FROM
WHERE t1.f1 GROUP BY t1.f1))';
EXECUTE stmt;
1
-1
EXECUTE stmt;
1
-1
DEALLOCATE PREPARE stmt;
DROP TABLE t1;
End of 5.1 tests
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_group.result b/mysql-test/r/func_group.result
index 0a1d136b55e..c39a226303b 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;
@@ -1865,7 +1868,7 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'j'
@@ -1891,7 +1894,7 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
#
# 3) Test that subquery materialization is setup for query with
@@ -1915,7 +1918,7 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
#
# 4) Test that subquery materialization is setup for query with
@@ -1930,6 +1933,8 @@ 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
@@ -1938,8 +1943,9 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
@@ -1964,8 +1970,8 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
+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
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_str.result b/mysql-test/r/func_str.result
index e08a0eef906..f2588af733d 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -2550,6 +2550,8 @@ 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
@@ -2560,6 +2562,7 @@ 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 (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/gis.result b/mysql-test/r/gis.result
index b0938c8f131..7624544014a 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -968,7 +968,7 @@ COUNT(*)
EXPLAIN
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref p p 28 const 1 Using where
+1 SIMPLE t2 ref p p 28 const # Using where
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
COUNT(*)
2
@@ -1061,39 +1061,9 @@ drop table t1;
#
create table t1(a char(32) not null) engine=myisam;
create spatial index i on t1 (a);
-ERROR 42000: A SPATIAL index may only contain a geometrical type column
+ERROR HY000: Incorrect arguments to SPATIAL INDEX
drop table t1;
End of 5.1 tests
-CREATE TABLE t1(
-col0 BINARY NOT NULL,
-col2 TIMESTAMP,
-SPATIAL INDEX i1 (col0)
-) ENGINE=MyISAM;
-ERROR 42000: A SPATIAL index may only contain a geometrical type column
-CREATE TABLE t1 (
-col0 BINARY NOT NULL,
-col2 TIMESTAMP
-) ENGINE=MyISAM;
-CREATE SPATIAL INDEX idx0 ON t1(col0);
-ERROR 42000: A SPATIAL index may only contain a geometrical type column
-ALTER TABLE t1 ADD SPATIAL INDEX i1 (col0);
-ERROR 42000: A SPATIAL index may only contain a geometrical type column
-CREATE TABLE t2 (
-col0 INTEGER NOT NULL,
-col1 POINT,
-col2 POINT
-);
-CREATE SPATIAL INDEX idx0 ON t2 (col1, col2);
-ERROR HY000: Incorrect arguments to SPATIAL INDEX
-CREATE TABLE t3 (
-col0 INTEGER NOT NULL,
-col1 POINT,
-col2 LINESTRING,
-SPATIAL INDEX i1 (col1, col2)
-);
-ERROR HY000: Incorrect arguments to SPATIAL INDEX
-DROP TABLE t1;
-DROP TABLE t2;
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
diff --git a/mysql-test/r/greedy_optimizer.result b/mysql-test/r/greedy_optimizer.result
index f8ca61f8ffc..74fe9980958 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)
@@ -202,28 +204,28 @@ 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 (flat, BNL join)
+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 (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 (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 (flat, BNL join)
+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 (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 (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 Using where
@@ -231,11 +233,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -243,11 +245,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -255,11 +257,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -267,11 +269,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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
@@ -287,7 +289,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -299,7 +301,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -311,7 +313,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -323,7 +325,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -335,7 +337,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -347,35 +349,35 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
+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 (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 (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 (flat, BNL join)
+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 (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 (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 Using where
@@ -383,11 +385,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -395,11 +397,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -407,11 +409,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -419,11 +421,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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
@@ -443,7 +445,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -455,55 +457,55 @@ id select_type table type possible_keys key key_len ref rows Extra
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 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 (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 (flat, BNL join)
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 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 (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 (flat, BNL join)
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 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 (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 (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 (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
+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 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 (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 (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 (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
+Last_query_cost 844.037037
set optimizer_search_depth=1;
select @@optimizer_search_depth;
@@optimizer_search_depth
@@ -519,7 +521,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -531,7 +533,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -543,7 +545,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -555,7 +557,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -567,7 +569,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -579,7 +581,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -595,7 +597,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -607,55 +609,55 @@ id select_type table type possible_keys key key_len ref rows Extra
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 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 (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 (flat, BNL join)
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 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 (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 (flat, BNL join)
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 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 (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 (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 (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
+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 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 (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 (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 (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
+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);
@@ -734,3 +736,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 141444886d8..b57bc21524e 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -451,6 +451,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
@@ -469,6 +471,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',
@@ -1540,12 +1543,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 PRIMARY,i2 PRIMARY 4 NULL 144 Using index
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 func 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 144
+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;
@@ -1554,11 +1560,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 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;
DROP TABLE t1, t2;
CREATE TABLE t1(
a INT,
diff --git a/mysql-test/r/group_min_max.result b/mysql-test/r/group_min_max.result
index f3457c43e00..5c46e65411d 100644
--- a/mysql-test/r/group_min_max.result
+++ b/mysql-test/r/group_min_max.result
@@ -1424,6 +1424,8 @@ 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
@@ -1455,6 +1457,7 @@ 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;
@@ -1481,6 +1484,8 @@ 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
@@ -1512,6 +1517,7 @@ 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
@@ -2403,7 +2409,7 @@ 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 <subquery2> ALL distinct_key NULL NULL NULL 8 Using where
1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 2 Using index
-2 SUBQUERY t1 range NULL a 5 NULL 8 Using index for group-by
+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
@@ -2927,6 +2933,251 @@ ORDER BY min_a;
min_a
NULL
DROP TABLE t1;
+#
+# LP BUG#888456 Wrong result with DISTINCT , ANY , subquery_cache=off , NOT NULL
+#
+CREATE TABLE t1 ( a int NOT NULL) ;
+INSERT INTO t1 VALUES (28),(29),(9);
+CREATE TABLE t2 ( a int, KEY (a)) ;
+INSERT INTO t2 VALUES (1),(1),(1),(4),(4),(5),(5),(8),(8),(9);
+explain select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+2 DEPENDENT SUBQUERY t2 index a a 5 NULL 10 Using where; Using index
+select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
+(select t2.a from t2 where t2.a >= t1.a group by t2.a)
+NULL
+NULL
+9
+drop table t1, t2;
+#
+# LP BUG#900375 Wrong result with derived_merge=ON, DISTINCT or GROUP BY, EXISTS
+#
+CREATE TABLE t1 ( a INT, b INT, KEY (b) );
+INSERT INTO t1 VALUES
+(100,10),(101,11),(102,12),(103,13),(104,14),
+(105,15),(106,16),(107,17),(108,18),(109,19);
+EXPLAIN
+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 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
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+EXPLAIN
+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 (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
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+100 10
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+101 11
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+102 12
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+103 13
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+104 14
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+105 15
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+106 16
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+107 17
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+108 18
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+109 19
+drop table t1;
End of 5.1 tests
#
# WL#3220 (Loose index scan for COUNT DISTINCT)
diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result
index e698d31e1ea..0f9da2ea3b6 100644
--- a/mysql-test/r/index_merge_innodb.result
+++ b/mysql-test/r/index_merge_innodb.result
@@ -686,6 +686,8 @@ 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)
@@ -711,6 +713,7 @@ 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
diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result
index 8953682ddb7..b560c1e5176 100644
--- a/mysql-test/r/index_merge_myisam.result
+++ b/mysql-test/r/index_merge_myisam.result
@@ -285,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> 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);
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 8443facbbd6..fcb40dae4ff 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1271,6 +1271,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,
@@ -1284,6 +1286,7 @@ 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> 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));
diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result
index b3b59bcdea6..08238289330 100644
--- a/mysql-test/r/innodb_icp.result
+++ b/mysql-test/r/innodb_icp.result
@@ -412,6 +412,7 @@ 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"
#
@@ -430,8 +431,8 @@ SELECT * FROM t1
WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition
+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
@@ -701,5 +702,111 @@ 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 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;
set optimizer_switch=@innodb_icp_tmp;
set storage_engine= @save_storage_engine;
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 cbf60d7184b..d8230826048 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);
@@ -896,7 +898,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -1349,3 +1351,4 @@ 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;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result
index 1ef17b0763e..07ceb573f85 100644
--- a/mysql-test/r/join_cache.result
+++ b/mysql-test/r/join_cache.result
@@ -40,6 +40,7 @@ COUNT(*)
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
@@ -313,8 +314,8 @@ 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)
+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
@@ -453,7 +454,7 @@ 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=default;
+set join_cache_level=1;
set join_buffer_size=256;
show variables like 'join_buffer_size';
Variable_name Value
@@ -776,7 +777,7 @@ Variable_name Value
join_buffer_size 131072
show variables like 'join_cache_level';
Variable_name Value
-join_cache_level 1
+join_cache_level 2
DROP DATABASE world;
CREATE DATABASE world;
use world;
@@ -2690,7 +2691,7 @@ Variable_name Value
join_buffer_size 131072
show variables like 'join_cache_level';
Variable_name Value
-join_cache_level 1
+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;
@@ -3878,6 +3879,7 @@ 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
@@ -3928,8 +3930,8 @@ EXPLAIN
SELECT t3.a FROM t1,t2,t3 WHERE t1.a = t3.a AND t1.b = t3.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using where
-1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using join buffer (flat, BNL join)
-1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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
@@ -4401,18 +4403,13 @@ INSERT INTO t2 VALUES
(1, 12, 102), (8, 81, 801), (7, 70, 700), (12, 120, 1200),
(8, 82, 802), (1, 13, 103), (1, 14, 104), (3, 31, 301),
(1, 15, 105), (8, 83, 803), (7, 71, 701);
-INSERT INTO t2 VALUES
-(108, 80, 800), (101, 10, 100), (101, 11, 101), (103, 30, 300),
-(101, 12, 102), (108, 81, 801), (107, 70, 700), (1012, 120, 1200),
-(108, 82, 802), (101, 13, 103), (101, 14, 104), (103, 31, 301),
-(101, 15, 105), (108, 83, 803), (107, 71, 701);
SET SESSION join_cache_level = 4;
SET SESSION join_buffer_size = 256;
EXPLAIN
SELECT t1.a, t2.c FROM t1,t2 WHERE t1.a=t2.a AND t2.b=99;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 ALL NULL NULL NULL NULL 36
-1 SIMPLE t2 ALL idx NULL NULL NULL 30 Using where; Using join buffer (flat, BNL join)
+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;
@@ -5140,8 +5137,8 @@ EXPLAIN
SELECT * FROM (SELECT DISTINCT * FROM t1) t
WHERE t.a IN (SELECT t2.a FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL key0 NULL NULL NULL 3 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY <derived2> ALL key0 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);
@@ -5173,8 +5170,8 @@ SET SESSION join_cache_level=3;
EXPLAIN
SELECT * FROM t1 WHERE (t1.b) IN (SELECT c FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where; Start temporary
-1 PRIMARY t2 hash_index c #hash#c:c 5:5 test.t1.b 8 End temporary; Using join buffer (flat, BNLH join)
+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
@@ -5182,4 +5179,217 @@ a b
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 <subquery3> ALL distinct_key NULL NULL NULL 2
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 Using where
+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;
set @@optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_nested.result b/mysql-test/r/join_nested.result
index fb4ebb3c4b7..dfb1a8c72d3 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);
@@ -1842,4 +1845,5 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`b` AS `b` from `test`.`t1` left join (`test`.`t2` left join `test`.`t3` on(((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`b` = `test`.`t1`.`a`))) left join `test`.`t4` on((`test`.`t4`.`b` = `test`.`t3`.`a`))) on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where isnull(`test`.`t3`.`a`)
DROP TABLE t1,t2,t3,t4;
+SET optimizer_switch=@save_optimizer_switch;
End of 5.0 tests
diff --git a/mysql-test/r/join_nested_jcl6.result b/mysql-test/r/join_nested_jcl6.result
index ff5a31b599b..69eb4532c73 100644
--- a/mysql-test/r/join_nested_jcl6.result
+++ b/mysql-test/r/join_nested_jcl6.result
@@ -7,7 +7,12 @@ 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);
@@ -1851,6 +1856,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`b` AS `b` from `test`.`t1` left join (`test`.`t2` left join `test`.`t3` on(((`test`.`t2`.`a` = `test`.`t1`.`a`) and (`test`.`t3`.`b` = `test`.`t1`.`a`))) left join `test`.`t4` on(((`test`.`t4`.`b` = `test`.`t3`.`a`) and (`test`.`t3`.`a` is not null)))) on((`test`.`t2`.`a` = `test`.`t1`.`a`)) where isnull(`test`.`t3`.`a`)
DROP TABLE t1,t2,t3,t4;
+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));
@@ -1960,5 +1966,7 @@ DROP TABLE t5,t6,t7,t8;
set join_cache_level=default;
show variables like 'join_cache_level';
Variable_name Value
-join_cache_level 1
+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 49ea07c5dff..16913864f5d 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,
@@ -1899,3 +1902,4 @@ b b a b
DEALLOCATE PREPARE stmt;
SET SESSION join_cache_level=default;
DROP TABLE t1,t2,t3;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/join_outer_jcl6.result b/mysql-test/r/join_outer_jcl6.result
index 4a53ff636cb..7605af40a6f 100644
--- a/mysql-test/r/join_outer_jcl6.result
+++ b/mysql-test/r/join_outer_jcl6.result
@@ -7,7 +7,12 @@ 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,
@@ -1908,8 +1913,11 @@ b b a b
DEALLOCATE PREPARE stmt;
SET SESSION join_cache_level=default;
DROP TABLE t1,t2,t3;
+SET optimizer_switch=@save_optimizer_switch;
set join_cache_level=default;
show variables like 'join_cache_level';
Variable_name Value
-join_cache_level 1
+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/maria_icp.result b/mysql-test/r/maria_icp.result
index 255ec069eb0..5739bbaa90c 100644
--- a/mysql-test/r/maria_icp.result
+++ b/mysql-test/r/maria_icp.result
@@ -412,6 +412,7 @@ 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"
#
@@ -436,8 +437,8 @@ SELECT * FROM t1
WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition
+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
@@ -707,5 +708,111 @@ 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;
set storage_engine= @save_storage_engine;
set optimizer_switch=@maria_icp_tmp;
diff --git a/mysql-test/r/maria_mrr.result b/mysql-test/r/maria_mrr.result
index c94f16ea1fb..d0bf94d7dab 100644
--- a/mysql-test/r/maria_mrr.result
+++ b/mysql-test/r/maria_mrr.result
@@ -352,6 +352,8 @@ 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)
@@ -374,6 +376,7 @@ 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
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index d87d8c0fe3b..ca72521a819 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -665,8 +665,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;
#
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index e179d7ec207..2a2197e7f98 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -2470,6 +2470,30 @@ CARDINALITY
DROP TABLE t1;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
SET myisam_repair_threads=@@global.myisam_repair_threads;
+#
+# BUG#11757032 - 49030: OPTIMIZE TABLE BREAKS MYISAM TABLE WHEN
+# USING MYISAM_USE_MMAP ON WINDOWS
+#
+SET GLOBAL myisam_use_mmap=1;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(1),(2);
+DELETE FROM t1 WHERE a=1;
+FLUSH TABLE t1;
+LOCK TABLE t1 WRITE;
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+INSERT INTO t1 VALUES(3);
+UNLOCK TABLES;
+SELECT * FROM t1;
+a
+2
+3
+CHECK TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+DROP TABLE t1;
+SET GLOBAL myisam_use_mmap=default;
End of 5.1 tests
#
# Bug#51327 MyISAM table is automatically repaired on ALTER
diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result
index d855c9d439b..e4343a21606 100644
--- a/mysql-test/r/myisam_icp.result
+++ b/mysql-test/r/myisam_icp.result
@@ -410,6 +410,7 @@ 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"
#
@@ -434,8 +435,8 @@ SELECT * FROM t1
WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition
+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
@@ -705,6 +706,112 @@ 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;
drop table if exists t0, t1, t1i, t1m;
#
# BUG#826935 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed
@@ -755,6 +862,8 @@ 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
@@ -763,8 +872,8 @@ t2.b NOT IN (SELECT t4.b FROM t3 STRAIGHT_JOIN t4 WHERE t4.b <= 2 AND t4.c = 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 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 2
-2 SUBQUERY t4 range b b 5 NULL 1 Using index condition; Using where; Rowid-ordered scan; Using join buffer (flat, BNL join)
+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);
@@ -776,5 +885,6 @@ Warning 1292 Truncated incorrect DOUBLE value: 'c'
Warning 1292 Truncated incorrect DOUBLE value: 'c'
Warning 1292 Truncated incorrect DOUBLE value: 'c'
Warning 1292 Truncated incorrect DOUBLE value: 'c'
+SET optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2,t3,t4;
set optimizer_switch=@myisam_icp_tmp;
diff --git a/mysql-test/r/myisam_mrr.result b/mysql-test/r/myisam_mrr.result
index a85fb97fdbc..9dd3602bab7 100644
--- a/mysql-test/r/myisam_mrr.result
+++ b/mysql-test/r/myisam_mrr.result
@@ -350,9 +350,9 @@ 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; Using where; Using filesort
+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 dual where exists(select `test`.`t2`.`pk` from `test`.`t2` where isnull(`test`.`t2`.`int_key`) group by `test`.`t2`.`pk`)
+Note 1003 select min(1) AS `MIN(t1.pk)` from dual 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
diff --git a/mysql-test/r/mysqld--help-notwin.result b/mysql-test/r/mysqld--help-notwin.result
index 5531a1d8a18..0155a06a941 100644
--- a/mysql-test/r/mysqld--help-notwin.result
+++ b/mysql-test/r/mysqld--help-notwin.result
@@ -898,7 +898,7 @@ init-slave
interactive-timeout 28800
join-buffer-size 131072
join-buffer-space-limit 2097152
-join-cache-level 1
+join-cache-level 2
keep-files-on-create FALSE
key-buffer-size 134217728
key-cache-age-threshold 300
@@ -978,7 +978,7 @@ old-passwords FALSE
old-style-user-limits FALSE
optimizer-prune-level 1
optimizer-search-depth 62
-optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+optimizer-switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
performance-schema FALSE
performance-schema-events-waits-history-long-size 10000
performance-schema-events-waits-history-size 10
diff --git a/mysql-test/r/named_pipe.result b/mysql-test/r/named_pipe.result
index 1742ebe6e8b..82c758eaad9 100644
--- a/mysql-test/r/named_pipe.result
+++ b/mysql-test/r/named_pipe.result
@@ -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
@@ -1422,6 +1424,7 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+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
diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index f440094c5ee..270e74ddf52 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -179,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)
@@ -217,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);
diff --git a/mysql-test/r/partition_innodb_plugin.result b/mysql-test/r/partition_innodb_plugin.result
index 2c2017cb83d..03163e972b5 100644
--- a/mysql-test/r/partition_innodb_plugin.result
+++ b/mysql-test/r/partition_innodb_plugin.result
@@ -1,3 +1,26 @@
+#
+# Bug#11766879/Bug#60106: DIFF BETWEEN # OF INDEXES IN MYSQL VS INNODB,
+# PARTITONING, ON INDEX CREATE
+#
+call mtr.add_suppression("contains 2 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MySQL");
+CREATE TABLE t1 (
+id bigint NOT NULL AUTO_INCREMENT,
+time date,
+id2 bigint not null,
+PRIMARY KEY (id,time)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8
+/*!50100 PARTITION BY RANGE(TO_DAYS(time))
+(PARTITION p10 VALUES LESS THAN (734708) ENGINE = InnoDB,
+PARTITION p20 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;
+INSERT INTO t1 (time,id2) VALUES ('2011-07-24',1);
+INSERT INTO t1 (time,id2) VALUES ('2011-07-25',1);
+INSERT INTO t1 (time,id2) VALUES ('2011-07-25',1);
+CREATE UNIQUE INDEX uk_time_id2 on t1(time,id2);
+ERROR 23000: Duplicate entry '2011-07-25-1' for key 'uk_time_id2'
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+3
+DROP TABLE t1;
call mtr.add_suppression("InnoDB: Error: table `test`.`t1` .* InnoDB internal");
#
# Bug#55091: Server crashes on ADD PARTITION after a failed attempt
diff --git a/mysql-test/r/pool_of_threads.result b/mysql-test/r/pool_of_threads.result
index 74ea7ba12eb..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,
@@ -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
@@ -1422,6 +1426,7 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+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
@@ -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 4747511bdb5..7d793f16c1a 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -151,6 +151,8 @@ c32 set('monday', 'tuesday', 'wednesday')
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 ;
@@ -178,6 +180,7 @@ 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;
@@ -3013,6 +3016,8 @@ 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
@@ -3027,6 +3032,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index e23dbaa9903..e35012e2218 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -1051,6 +1051,23 @@ Qcache_inserts 1
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 1
+set 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 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);
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 4ae9197823a..57e0ca97999 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
@@ -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
@@ -5088,6 +5091,33 @@ 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;
#
# Bug #58422: Incorrect result when OUTER JOIN'ing
# with an empty table
@@ -5204,3 +5234,40 @@ avg(distinct(t1.a))
0
DROP TABLE t1;
# End of test BUG#57203
+# 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;
diff --git a/mysql-test/r/select_jcl6.result b/mysql-test/r/select_jcl6.result
index 4a5ef4879d1..bfd42910508 100644
--- a/mysql-test/r/select_jcl6.result
+++ b/mysql-test/r/select_jcl6.result
@@ -7,9 +7,14 @@ 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
@@ -2205,10 +2210,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
@@ -5097,6 +5102,33 @@ 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;
#
# Bug #58422: Incorrect result when OUTER JOIN'ing
# with an empty table
@@ -5213,8 +5245,47 @@ avg(distinct(t1.a))
0
DROP TABLE t1;
# End of test BUG#57203
+# 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;
set join_cache_level=default;
show variables like 'join_cache_level';
Variable_name Value
-join_cache_level 1
+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 4ae9197823a..57e0ca97999 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
@@ -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
@@ -5088,6 +5091,33 @@ 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;
#
# Bug #58422: Incorrect result when OUTER JOIN'ing
# with an empty table
@@ -5204,3 +5234,40 @@ avg(distinct(t1.a))
0
DROP TABLE t1;
# End of test BUG#57203
+# 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;
diff --git a/mysql-test/r/shm.result b/mysql-test/r/shm.result
index 1b5c284e8b5..d4298fb2d09 100644
--- a/mysql-test/r/shm.result
+++ b/mysql-test/r/shm.result
@@ -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
@@ -1422,6 +1424,7 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+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
diff --git a/mysql-test/r/ssl.result b/mysql-test/r/ssl.result
index bb278a0fa5d..53fbb1988e7 100644
--- a/mysql-test/r/ssl.result
+++ b/mysql-test/r/ssl.result
@@ -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
@@ -1425,6 +1427,7 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+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
diff --git a/mysql-test/r/ssl_compress.result b/mysql-test/r/ssl_compress.result
index 908f0892734..e7ae7885059 100644
--- a/mysql-test/r/ssl_compress.result
+++ b/mysql-test/r/ssl_compress.result
@@ -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
@@ -1428,6 +1430,7 @@ explain select companynr,companyname from t4 left join t2 using (companynr) wher
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where
+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
diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result
index 6782750eef6..91a120313ae 100644
--- a/mysql-test/r/status.result
+++ b/mysql-test/r/status.result
@@ -149,7 +149,7 @@ 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
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 6b6db4f5f2c..7d3877e678d 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -3,6 +3,7 @@ drop view if exists v2;
set @subselect_tmp=@@optimizer_switch;
set @@optimizer_switch=ifnull(@optimizer_switch_for_subselect_test,
"semijoin=on,firstmatch=on,loosescan=on,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)
@@ -201,6 +202,8 @@ 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
@@ -209,6 +212,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
@@ -1370,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 0 0.00 Using index condition
+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`))
@@ -1395,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
@@ -1658,7 +1662,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`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);
@@ -1666,7 +1670,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`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);
@@ -1682,7 +1686,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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);
@@ -1698,7 +1702,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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
@@ -2970,15 +2974,15 @@ explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FR
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 10 func,func 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 9 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` 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
+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') 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));
@@ -3560,7 +3564,7 @@ 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 23 test.t1.a,test.t1.b 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+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
@@ -3572,7 +3576,7 @@ 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 23 test.t1.a,test.t1.b 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+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);
@@ -4356,6 +4360,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');
@@ -4387,6 +4394,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -4512,20 +4520,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 5 const 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
Warnings:
-Note 1003 select 1 AS `1` from <materialize> (select 1 from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`1` = 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 <subquery2> const distinct_key distinct_key 5 const 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
+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 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`1` = 1)
+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.
@@ -4601,6 +4612,32 @@ 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';
+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;
End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
@@ -4843,8 +4880,6 @@ SELECT * FROM t1
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
pk a
1 10
-3 30
-2 20
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
INSERT INTO t1 VALUES (1,NULL), (9,NULL);
@@ -5556,8 +5591,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 24 Using where
1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
-2 SUBQUERY it2 ALL NULL NULL NULL NULL 4
-2 SUBQUERY it3 ALL NULL NULL NULL NULL 6 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
@@ -5598,16 +5633,19 @@ 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 Start temporary
-1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; Using join buffer (flat, BNL join)
-1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index; End temporary
+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
@@ -5615,18 +5653,21 @@ DROP table t1,t2;
#
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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+2 DEPENDENT 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:
@@ -5838,6 +5879,8 @@ 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
@@ -5852,9 +5895,9 @@ 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;
End of 5.3 tests
-End of 5.5 tests.
#
# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
#
@@ -5887,10 +5930,13 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (a INT, b INT, INDEX (a));
INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ref a a 5 const 1
+set optimizer_switch=@tmp_optimizer_switch;
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
@@ -5969,7 +6015,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
-2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
DROP TABLE t1,t2;
#
# lp:826279: assertion failure with GROUP BY a result of subquery
@@ -6031,5 +6077,211 @@ set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquer
select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select 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;
+# 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 a7b6e40d9c9..41c445329cb 100644
--- a/mysql-test/r/subselect2.result
+++ b/mysql-test/r/subselect2.result
@@ -125,9 +125,9 @@ 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 t4 ALL PRIMARY NULL NULL NULL 10
-1 PRIMARY t2 ALL DDOCTYPEID_IDX,DFOLDERID_IDX NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY 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
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
@@ -146,4 +146,37 @@ 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;
set optimizer_switch=@subselect2_test_tmp;
diff --git a/mysql-test/r/subselect3.result b/mysql-test/r/subselect3.result
index 1a87c268d29..833d6f203c2 100644
--- a/mysql-test/r/subselect3.result
+++ b/mysql-test/r/subselect3.result
@@ -1,6 +1,7 @@
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),
@@ -105,7 +106,7 @@ oref a
1 1
show status like '%Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 14
+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';
@@ -1046,8 +1047,8 @@ 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; Start temporary
-2 DEPENDENT SUBQUERY Z ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+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
@@ -1117,12 +1118,15 @@ a
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));
@@ -1132,8 +1136,8 @@ create table t3 (a int);
insert into t3 select A.a + 10*B.a from t0 A, t0 B;
explain select * from t3 where a in (select kp1 from t1 where kp1<20);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where
-1 PRIMARY t1 ref kp1 kp1 5 test.t3.a 1 Using index; FirstMatch(t3)
+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
@@ -1175,7 +1179,7 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+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
@@ -1191,27 +1195,27 @@ insert into t3 select * from t1;
insert into t3 values (1),(2);
explain select * from t2 where a in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+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 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+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 Start temporary
-1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+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 Start temporary
-1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+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 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+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;
@@ -1223,8 +1227,8 @@ 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; Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+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
@@ -1269,11 +1273,11 @@ 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 range a a 5 NULL 8 Using where; Using index; LooseScan
+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 range a a 5 NULL 8 Using where; Using index; LooseScan
+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;
@@ -1284,16 +1288,16 @@ 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 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; End temporary; Using join buffer (flat, BNL join)
+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;
Warnings:
Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead
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 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 100 Using where; End temporary; Using join buffer (flat, BNL join)
+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;
@@ -1304,8 +1308,8 @@ 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 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+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
@@ -1317,8 +1321,8 @@ 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 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; End temporary; Using join buffer (flat, BNL join)
+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
@@ -1331,10 +1335,10 @@ 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 Start temporary
-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 (flat, BNL join)
-1 PRIMARY Z ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+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;
@@ -1471,7 +1475,7 @@ FROM t3
);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
+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`))))))))
diff --git a/mysql-test/r/subselect3_jcl6.result b/mysql-test/r/subselect3_jcl6.result
index 791040c8502..5d7fee48d87 100644
--- a/mysql-test/r/subselect3_jcl6.result
+++ b/mysql-test/r/subselect3_jcl6.result
@@ -7,9 +7,11 @@ 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),
@@ -114,7 +116,7 @@ oref a
1 1
show status like '%Handler_read_rnd_next';
Variable_name Value
-Handler_read_rnd_next 14
+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';
@@ -1055,8 +1057,8 @@ 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; Start temporary
-2 DEPENDENT SUBQUERY Z hash_ALL NULL #hash#$hj 5 test.Y.a 2 Using where; End temporary; Using join buffer (flat, BNLH join)
+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
@@ -1126,12 +1128,15 @@ a
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));
@@ -1141,8 +1146,8 @@ create table t3 (a int);
insert into t3 select A.a + 10*B.a from t0 A, t0 B;
explain select * from t3 where a in (select kp1 from t1 where kp1<20);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t3 ALL NULL NULL NULL NULL 100 Using where
-1 PRIMARY t1 ref kp1 kp1 5 test.t3.a 1 Using index; FirstMatch(t3)
+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
@@ -1184,7 +1189,7 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+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
@@ -1200,27 +1205,27 @@ 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; Start temporary
-1 PRIMARY t1 hash_ALL NULL #hash#$hj 4 test.t2.a 4 Using where; End temporary; Using join buffer (flat, BNLH join)
+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; Start temporary
-1 PRIMARY t2 hash_ALL NULL #hash#$hj 5 test.t2.a 2 Using where; End temporary; Using join buffer (flat, BNLH join)
+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 Start temporary
-1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+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 Start temporary
-1 PRIMARY t3 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+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; Start temporary
-1 PRIMARY t1 hash_ALL NULL #hash#$hj 6 test.t1.a 2 Using where; End temporary; Using join buffer (flat, BNLH join)
+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;
@@ -1232,8 +1237,8 @@ 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; Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
+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
@@ -1278,11 +1283,11 @@ 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 range a a 5 NULL 8 Using where; Using index; LooseScan
+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 range a a 5 NULL 8 Using where; Using index; LooseScan
+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;
@@ -1293,16 +1298,16 @@ 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; Start temporary
-1 PRIMARY t2 hash_ALL NULL #hash#$hj 10 test.t1.a,test.t1.b 100 Using where; End temporary; Using join buffer (flat, BNLH join)
+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;
Warnings:
Warning 1287 'optimizer-search-depth=63' is deprecated and will be removed in a future release. Please use a search depth less than 63 instead
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; Start temporary
-1 PRIMARY t2 hash_ALL NULL #hash#$hj 10 test.t1.a,test.t1.b 100 Using where; End temporary; Using join buffer (flat, BNLH join)
+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;
@@ -1313,8 +1318,8 @@ 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 Using where; Start temporary
-1 PRIMARY t1 hash_ALL NULL #hash#$hj 3 test.t0.a 4 Using where; End temporary; Using join buffer (flat, BNLH join)
+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
@@ -1326,8 +1331,8 @@ 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 Using where; Start temporary
-1 PRIMARY t1 hash_ALL NULL #hash#$hj 4 test.t0.a 4 Using where; End temporary; Using join buffer (flat, BNLH join)
+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
@@ -1340,10 +1345,10 @@ 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 Using where; Start temporary
-1 PRIMARY X hash_ALL NULL #hash#$hj 5 test.t1.a 6 Using where; Using join buffer (flat, BNLH join)
-1 PRIMARY Y hash_ALL NULL #hash#$hj 5 test.t1.b 6 Using where; Using join buffer (incremental, BNLH join)
-1 PRIMARY Z hash_ALL NULL #hash#$hj 5 test.t1.c 6 Using where; End temporary; Using join buffer (incremental, BNLH join)
+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;
@@ -1480,7 +1485,7 @@ FROM t3
);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00
+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`))))))))
@@ -1550,5 +1555,6 @@ set @@optimizer_switch=@subselect3_tmp;
set join_cache_level=default;
show variables like 'join_cache_level';
Variable_name Value
-join_cache_level 1
+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 de9cdd729f7..1fd638fd42c 100644
--- a/mysql-test/r/subselect4.result
+++ b/mysql-test/r/subselect4.result
@@ -342,8 +342,8 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+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
@@ -357,14 +357,14 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+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);
@@ -380,8 +380,8 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+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
@@ -395,14 +395,14 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+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
@@ -417,8 +417,8 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+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
@@ -432,14 +432,14 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 12 Using where; Using join buffer (flat, BNL join)
+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;
@@ -562,10 +562,10 @@ WHERE f3 = (
SELECT t1.f3 FROM t1
WHERE ( t1.f10 ) IN ( SELECT f11 FROM t2 GROUP BY f11 ));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref f3 f3 5 const 0 Using index condition
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 5 test.t1.f10 1
-3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary
+1 PRIMARY t1 ref f3 f3 5 const 0 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 5 func 1
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
SELECT * FROM t1
WHERE f3 = (
SELECT t1.f3 FROM t1
@@ -577,15 +577,44 @@ WHERE f3 = (
SELECT f3 FROM t1
WHERE ( f10, f10 ) IN ( SELECT f11, f11 FROM t2 GROUP BY f11 ));
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref f3 f3 5 const 0 Using index condition
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 10 test.t1.f10,test.t1.f10 1
-3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using temporary
+1 PRIMARY t1 ref f3 f3 5 const 0 Using where
+2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+2 SUBQUERY <subquery3> eq_ref distinct_key distinct_key 10 func,func 1
+3 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
SELECT * FROM t1
WHERE f3 = (
SELECT f3 FROM t1
WHERE ( f10, f10 ) IN ( SELECT f11, f11 FROM t2 GROUP BY f11 ));
f1 f3 f10
+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;
#
@@ -599,21 +628,21 @@ 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
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+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
@@ -628,14 +657,14 @@ 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
+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 SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
+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
@@ -785,21 +814,21 @@ 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
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+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
@@ -814,14 +843,14 @@ 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
+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 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Rowid-ordered scan
+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
@@ -1007,7 +1036,7 @@ 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 SUBQUERY t1 index NULL f2 4 NULL 2 Using index
+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);
@@ -1075,6 +1104,10 @@ 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
@@ -1091,6 +1124,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -1098,7 +1132,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2 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
@@ -1107,9 +1141,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 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 SUBQUERY 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()
@@ -1177,7 +1212,7 @@ EXPLAIN
SELECT * FROM t1 WHERE
(SELECT f2 FROM t2
WHERE f4 <= ALL
-(SELECT SQ1_t1.f4
+(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
@@ -1383,7 +1418,7 @@ 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
+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
@@ -1469,72 +1504,73 @@ CREATE TABLE t2 (f1b int, f2b int not null, f3b varchar(3) not null, PRIMARY KEY
INSERT INTO t2 VALUES
(10,5,'d1d');
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off';
+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 f2 , f1 FROM t0 GROUP BY f2 , f1 );
+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
+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 f2 , f1 FROM t0 GROUP BY f2 , f1 );
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
f1 f2
8 8
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'u'
EXPLAIN
-SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT 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);
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
-SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT f1a, f2a FROM t1 GROUP BY f1a, f2a);
+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 f1a FROM t1 GROUP BY f1a, f2a);
+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
-SELECT * FROM t2 WHERE (f1b) IN (SELECT f1a FROM t1 GROUP BY f1a, f2a);
+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 = 'materialization=on';
+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 f2 , f1 FROM t0 GROUP BY f2 , f1 );
+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 SUBQUERY t0 ALL NULL NULL NULL NULL 2
+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 f2 , f1 FROM t0 GROUP BY f2 , f1 );
+WHERE ( alias2.f1 , alias2.f2 ) IN ( SELECT max(f2) , f1 FROM t0 GROUP BY f2 , f1 );
f1 f2
8 8
Warnings:
Warning 1292 Truncated incorrect DOUBLE value: 'u'
EXPLAIN
-SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT 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);
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
-SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT f1a, f2a FROM t1 GROUP BY f1a, f2a);
+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 f1a FROM t1 GROUP BY f1a, f2a);
+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
-SELECT * FROM t2 WHERE (f1b) IN (SELECT f1a FROM t1 GROUP BY f1a, f2a);
+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;
@@ -1619,7 +1655,7 @@ 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 Using temporary
+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
@@ -1639,10 +1675,10 @@ WHERE t2.f2 = (SELECT f2 FROM t3
WHERE EXISTS (SELECT DISTINCT f1 FROM t4))
AND t2.f2 = t1.f1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref f1 f1 5 const 0 Using index condition
+1 PRIMARY 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; Using temporary
+3 SUBQUERY t4 index NULL f1 5 NULL 2 Using index
SELECT *
FROM t1, t2
WHERE t2.f2 = (SELECT f2 FROM t3
@@ -1656,10 +1692,10 @@ WHERE t2.f2 = (SELECT f2 FROM t3
WHERE EXISTS (SELECT DISTINCT f1 FROM t4) LIMIT 1)
AND t2.f2 = t1.f1;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ref f1 f1 5 const 0 Using index condition
+1 PRIMARY 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; Using temporary
+3 SUBQUERY t4 index NULL f1 5 NULL 2 Using index
SELECT *
FROM t1, t2
WHERE t2.f2 = (SELECT f2 FROM t3
@@ -1687,7 +1723,7 @@ FROM t1));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY t4 ALL NULL NULL NULL NULL 2
-3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+3 SUBQUERY t1 ALL NULL NULL NULL NULL 2
SELECT *
FROM t2, t3
WHERE t3.f1 = (
@@ -1733,7 +1769,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index NULL col_int_key 5 NULL 2 Using index
2 SUBQUERY SUBQUERY2_t1 index NULL col_int_key 5 NULL 2 Using index
2 SUBQUERY SUBQUERY2_t2 ALL col_varchar_key NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
-3 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+3 MATERIALIZED t1 ALL NULL NULL NULL NULL 2
SELECT col_int_key
FROM t2
WHERE (SELECT SUBQUERY2_t1.col_int_key
@@ -1758,7 +1794,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index NULL col_int_key 5 NULL 2 Using index
2 SUBQUERY SUBQUERY2_t1 index NULL col_int_key 5 NULL 2 Using index
2 SUBQUERY SUBQUERY2_t2 ALL col_varchar_key NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
-3 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+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
@@ -1786,7 +1822,7 @@ EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+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
@@ -1816,7 +1852,7 @@ EXPLAIN SELECT * FROM t1 JOIN v2 ON t1.f2 > 'a' WHERE v2.f3 IN ( SELECT f2 FROM
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+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
@@ -1848,7 +1884,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 system NULL NULL NULL NULL 1 Using temporary; Using filesort
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
-3 SUBQUERY t1 system NULL NULL NULL NULL 0 const row not found
+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
@@ -1880,7 +1916,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
1 PRIMARY t3 system NULL NULL NULL NULL 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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 ) ;
diff --git a/mysql-test/r/subselect_cache.result b/mysql-test/r/subselect_cache.result
index 4b0b4c0ead8..d8ac44005f9 100644
--- a/mysql-test/r/subselect_cache.result
+++ b/mysql-test/r/subselect_cache.result
@@ -1,5 +1,8 @@
drop table if exists t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
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);
@@ -1836,7 +1839,7 @@ set optimizer_switch='default,semijoin=off,materialization=on,subquery_cache=on'
explain select * from t1 where a in (select pk from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 15 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 10
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 10
flush status;
select * from t1 where a in (select pk from t2);
a b
@@ -3398,71 +3401,6 @@ WHERE table3 .`col_varchar_key` IN (
SELECT `col_varchar_key`
FROM t2 ) AND table1 .`col_varchar_key` OR table1 .`pk` ;
col_varchar_nokey
-Warnings:
-Warning 1292 Truncated incorrect DOUBLE value: 'w'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'k'
-Warning 1292 Truncated incorrect DOUBLE value: 'r'
-Warning 1292 Truncated incorrect DOUBLE value: 't'
-Warning 1292 Truncated incorrect DOUBLE value: 'j'
-Warning 1292 Truncated incorrect DOUBLE value: 'u'
-Warning 1292 Truncated incorrect DOUBLE value: 'h'
-Warning 1292 Truncated incorrect DOUBLE value: 'o'
-Warning 1292 Truncated incorrect DOUBLE value: 'k'
-Warning 1292 Truncated incorrect DOUBLE value: 'e'
-Warning 1292 Truncated incorrect DOUBLE value: 'n'
-Warning 1292 Truncated incorrect DOUBLE value: 't'
-Warning 1292 Truncated incorrect DOUBLE value: 'c'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'y'
-Warning 1292 Truncated incorrect DOUBLE value: 'f'
-Warning 1292 Truncated incorrect DOUBLE value: 'd'
-Warning 1292 Truncated incorrect DOUBLE value: 'v'
-Warning 1292 Truncated incorrect DOUBLE value: 'r'
-Warning 1292 Truncated incorrect DOUBLE value: 'a'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'y'
-Warning 1292 Truncated incorrect DOUBLE value: 'j'
-Warning 1292 Truncated incorrect DOUBLE value: 'd'
-Warning 1292 Truncated incorrect DOUBLE value: 'z'
-Warning 1292 Truncated incorrect DOUBLE value: 'e'
-Warning 1292 Truncated incorrect DOUBLE value: 'h'
-Warning 1292 Truncated incorrect DOUBLE value: 'b'
-Warning 1292 Truncated incorrect DOUBLE value: 's'
-Warning 1292 Truncated incorrect DOUBLE value: 'e'
-Warning 1292 Truncated incorrect DOUBLE value: 'j'
-Warning 1292 Truncated incorrect DOUBLE value: 'e'
-Warning 1292 Truncated incorrect DOUBLE value: 'f'
-Warning 1292 Truncated incorrect DOUBLE value: 'v'
-Warning 1292 Truncated incorrect DOUBLE value: 'x'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'c'
-Warning 1292 Truncated incorrect DOUBLE value: 'w'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'k'
-Warning 1292 Truncated incorrect DOUBLE value: 'r'
-Warning 1292 Truncated incorrect DOUBLE value: 't'
-Warning 1292 Truncated incorrect DOUBLE value: 'j'
-Warning 1292 Truncated incorrect DOUBLE value: 'u'
-Warning 1292 Truncated incorrect DOUBLE value: 'h'
-Warning 1292 Truncated incorrect DOUBLE value: 'o'
-Warning 1292 Truncated incorrect DOUBLE value: 'k'
-Warning 1292 Truncated incorrect DOUBLE value: 'e'
-Warning 1292 Truncated incorrect DOUBLE value: 'n'
-Warning 1292 Truncated incorrect DOUBLE value: 't'
-Warning 1292 Truncated incorrect DOUBLE value: 'c'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'y'
-Warning 1292 Truncated incorrect DOUBLE value: 'f'
-Warning 1292 Truncated incorrect DOUBLE value: 'd'
-Warning 1292 Truncated incorrect DOUBLE value: 'w'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'm'
-Warning 1292 Truncated incorrect DOUBLE value: 'k'
-Warning 1292 Truncated incorrect DOUBLE value: 'r'
-Warning 1292 Truncated incorrect DOUBLE value: 't'
drop table t1,t2;
set @@optimizer_switch= default;
set optimizer_switch='subquery_cache=on';
@@ -3573,5 +3511,6 @@ pk b
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
index 72362415b2b..b3507c97086 100644
--- a/mysql-test/r/subselect_extra.result
+++ b/mysql-test/r/subselect_extra.result
@@ -15,16 +15,16 @@ insert into t2 values ('2001-01-01 1:1:1'), ('2001-01-01 1:1:1');
flush tables;
EXPLAIN SELECT OUTR.dt FROM t1 AS OUTR WHERE OUTR.dt IN (SELECT INNR.dt FROM t2 AS INNR WHERE OUTR.dt IS NULL );
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY OUTR ALL NULL NULL NULL NULL 2 Using where; Start temporary
-1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+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; Start temporary
-1 PRIMARY INNR ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+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
@@ -67,8 +67,8 @@ explain extended
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary
-1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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))
@@ -79,8 +79,8 @@ explain extended
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary
-1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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))
@@ -308,7 +308,7 @@ EXPLAIN SELECT 1 FROM t1 WHERE a IN
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 SUBQUERY t1 ALL NULL NULL NULL NULL 144
+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;
@@ -321,7 +321,8 @@ EXPLAIN SELECT 1 FROM t2 WHERE a IN
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 index a a 5 NULL 4 Using index
-1 PRIMARY t1 ALL NULL NULL NULL NULL 144 Using where; FirstMatch(t2); Using join buffer (flat, BNL join)
+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
@@ -432,7 +433,7 @@ 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
+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
diff --git a/mysql-test/r/subselect_extra_no_semijoin.result b/mysql-test/r/subselect_extra_no_semijoin.result
index 5d592541e8b..773ee9898a4 100644
--- a/mysql-test/r/subselect_extra_no_semijoin.result
+++ b/mysql-test/r/subselect_extra_no_semijoin.result
@@ -311,7 +311,7 @@ EXPLAIN SELECT 1 FROM t1 WHERE a IN
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL PRIMARY 4 NULL 144 Using where; Using index
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 144
+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;
@@ -324,7 +324,7 @@ 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 SUBQUERY t1 ALL NULL NULL NULL NULL 144
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 144
DROP TABLE t1, t2;
#
# From derived_view.test
@@ -349,7 +349,7 @@ 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 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+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`.`t2` where <expr_cache><0>(<in_optimizer>(0,0 in ( <materialize> (select 0 from dual ), <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
@@ -362,7 +362,7 @@ 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 SUBQUERY t1 system NULL NULL NULL NULL 1 100.00
+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`.`t2` where <expr_cache><0>(<in_optimizer>(0,0 in ( <materialize> (select 0 from dual ), <primary_index_lookup>(0 in <temporary table> on distinct_key where ((0 = `<subquery2>`.`b`))))))
DROP VIEW v1;
diff --git a/mysql-test/r/subselect_innodb.result b/mysql-test/r/subselect_innodb.result
index b134e849bbe..60faea8853f 100644
--- a/mysql-test/r/subselect_innodb.result
+++ b/mysql-test/r/subselect_innodb.result
@@ -302,7 +302,7 @@ GROUP BY 1
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY t1 ALL NULL NULL NULL NULL 1
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 1 Using temporary; Using filesort
+3 SUBQUERY t3 ALL NULL NULL NULL NULL 1
SELECT MAX( f1 ) FROM t2
WHERE f2 >= (
SELECT SUM( f1 )
diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result
index 9a0a40e0ccc..5c750e8b078 100644
--- a/mysql-test/r/subselect_mat.result
+++ b/mysql-test/r/subselect_mat.result
@@ -3,6 +3,8 @@ 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;
@@ -46,7 +48,7 @@ explain extended
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+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');
@@ -57,9 +59,9 @@ explain extended
select * from t1 where a1 in (select b1 from t2 where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+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') group by `test`.`t2`.`b1` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t1`.`a1`,`test`.`t1`.`a1` in ( <materialize> (select `test`.`t2`.`b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <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
@@ -68,9 +70,9 @@ explain extended
select * from t1 where (a1, a2) in (select b1, b2 from t2 where b1 > '0' group by b1, b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+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') group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` where <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') ), <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
@@ -79,7 +81,7 @@ explain extended
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+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);
@@ -90,7 +92,7 @@ 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 SUBQUERY t2i index it2i1,it2i3 it2i1 # NULL 5 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');
@@ -98,13 +100,13 @@ a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
explain extended
-select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+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 SUBQUERY t2i range it2i1,it2i3 # 9 # 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 `test`.`t2i`.`b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`))))))
-select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+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
@@ -112,7 +114,7 @@ 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 SUBQUERY t2i index it2i1,it2i3 it2i3 # NULL 5 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');
@@ -120,13 +122,13 @@ a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
explain extended
-select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+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 SUBQUERY t2i range it2i1,it2i3 # # # 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`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2` ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery2>`.`b2`))))))
-select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+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
@@ -134,7 +136,7 @@ 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 SUBQUERY t2i range it2i1,it2i3 # # # 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);
@@ -145,7 +147,7 @@ explain extended
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
+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);
@@ -156,11 +158,11 @@ prepare st1 from "explain select * from t1 where (a1, a2) in (select b1, max(b2)
execute st1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t2i range NULL it2i3 9 NULL 3 Using index for group-by
+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 SUBQUERY t2i range NULL it2i3 9 NULL 3 Using index for group-by
+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
@@ -174,7 +176,7 @@ explain extended
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+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);
@@ -221,7 +223,7 @@ explain extended
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00
+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);
@@ -232,7 +234,7 @@ explain extended
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1i index NULL it1i3 18 NULL 3 100.00 Using where; Using index
-2 SUBQUERY t2i index NULL it2i3 18 NULL 5 100.00 Using index
+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);
@@ -285,9 +287,9 @@ where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-4 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
+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
@@ -304,9 +306,9 @@ where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
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 SUBQUERY t3i index NULL # # # 4 100.00 #
-4 SUBQUERY t2i index it2i2 # # # 5 100.00 #
-2 SUBQUERY t2i index it2i1,it2i3 # # # 5 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
@@ -325,11 +327,11 @@ b2 in (select c2 from t3 where c2 LIKE '%03')) and
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-6 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+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
@@ -349,10 +351,10 @@ b2 in (select c2 from t3 t3b where c2 LIKE '%03')) and
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-5 SUBQUERY t3c ALL NULL NULL NULL NULL 4 100.00 Using where
-6 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+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 SUBQUERY t3b ALL NULL NULL NULL NULL 4 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
@@ -381,18 +383,18 @@ where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
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 SUBQUERY t3 ALL NULL # # # 4 100.00 #
-6 SUBQUERY t2i index it2i2 # # # 5 100.00 #
-2 SUBQUERY t2 ALL NULL # # # 5 100.00 #
-4 SUBQUERY t3 ALL NULL # # # 4 100.00 #
-3 SUBQUERY t3 ALL NULL # # # 4 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 SUBQUERY t3i index NULL # # # 4 100.00 #
-10 SUBQUERY t2i index it2i2 # # # 5 100.00 #
-8 SUBQUERY t2i index it2i1,it2i3 # # # 5 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`))))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2` ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`)))))) and <expr_cache><`test`.`t1`.`a1`,`test`.`t1`.`a2`>(<in_optimizer>((`test`.`t1`.`a1`,`test`.`t1`.`a2`),(`test`.`t1`.`a1`,`test`.`t1`.`a2`) in ( <materialize> (select `test`.`t3`.`c1`,`test`.`t3`.`c2` from `test`.`t3` where <expr_cache><`test`.`t3`.`c1`,`test`.`t3`.`c2`>(<in_optimizer>((`test`.`t3`.`c1`,`test`.`t3`.`c2`),(`test`.`t3`.`c1`,`test`.`t3`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3`.`c1` in <temporary table> on distinct_key where ((`test`.`t3`.`c1` = `<subquery6>`.`b1`) and (`test`.`t3`.`c2` = `<subquery6>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1`.`a1` in <temporary table> on distinct_key where ((`test`.`t1`.`a1` = `<subquery5>`.`c1`) and (`test`.`t1`.`a2` = `<subquery5>`.`c2`)))))))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` where (<expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery8>`.`b1`) and (`test`.`t1i`.`a2` = `<subquery8>`.`b2`)))))) and <expr_cache><`test`.`t1i`.`a1`,`test`.`t1i`.`a2`>(<in_optimizer>((`test`.`t1i`.`a1`,`test`.`t1i`.`a2`),(`test`.`t1i`.`a1`,`test`.`t1i`.`a2`) in ( <materialize> (select `test`.`t3i`.`c1`,`test`.`t3i`.`c2` from `test`.`t3i` where <expr_cache><`test`.`t3i`.`c1`,`test`.`t3i`.`c2`>(<in_optimizer>((`test`.`t3i`.`c1`,`test`.`t3i`.`c2`),(`test`.`t3i`.`c1`,`test`.`t3i`.`c2`) in ( <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b2` > '0') ), <primary_index_lookup>(`test`.`t3i`.`c1` in <temporary table> on distinct_key where ((`test`.`t3i`.`c1` = `<subquery10>`.`b1`) and (`test`.`t3i`.`c2` = `<subquery10>`.`b2`)))))) ), <primary_index_lookup>(`test`.`t1i`.`a1` in <temporary table> on distinct_key where ((`test`.`t1i`.`a1` = `<subquery9>`.`c1`) and (`test`.`t1i`.`a2` = `<subquery9>`.`c2`))))))))
+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
@@ -415,8 +417,8 @@ where (a1, a2) in (select * from t1 where a1 > '0' UNION select * from t2 where
where (c1, c2) in (select b1, b2 from t2i where b2 > '0'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-5 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+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
@@ -438,8 +440,8 @@ a1 = c1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 PRIMARY t3 ALL NULL NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-5 SUBQUERY t2i index it2i2 it2i3 18 NULL 5 100.00 Using where; Using index
+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
@@ -485,7 +487,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
5 DEPENDENT SUBQUERY t3c ALL NULL NULL NULL NULL 4 100.00 Using where
6 DEPENDENT SUBQUERY t2i index_subquery it2i1,it2i2,it2i3 it2i3 18 func,func 2 100.00 Using index; Using where
2 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
-4 SUBQUERY t3b ALL NULL NULL NULL NULL 4 100.00 Using where
+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
@@ -622,7 +624,7 @@ from t1_16
where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+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)
@@ -651,7 +653,7 @@ from t1_16
where a1 in (select group_concat(b1) from t2_16 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -673,7 +675,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
2 DEPENDENT SUBQUERY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
3 DEPENDENT SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where
3 DEPENDENT SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+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;
@@ -735,7 +737,7 @@ from t1_512
where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+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)
@@ -749,7 +751,7 @@ from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -762,7 +764,7 @@ from t1_512
where a1 in (select group_concat(b1) from t2_512 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -842,7 +844,7 @@ from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -855,7 +857,7 @@ from t1_1024
where a1 in (select group_concat(b1) from t2_1024 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -935,7 +937,7 @@ from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -948,7 +950,7 @@ from t1_1025
where a1 in (select group_concat(b1) from t2_1025 group by b2);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -969,7 +971,7 @@ from t1bit
where (a1, a2) in (select b1, b2 from t2bit);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1bit ALL NULL NULL NULL NULL 3 100.00 Using where
-2 SUBQUERY t2bit ALL NULL NULL NULL NULL 3 100.00
+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)
@@ -1040,7 +1042,7 @@ explain extended
select a from t1 where a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 7 100.00 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
+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);
@@ -1054,7 +1056,7 @@ explain extended
select a from t1 where a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 100.00 Using where
+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);
@@ -1068,7 +1070,7 @@ explain extended
select a from t1 where a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+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);
@@ -1081,7 +1083,7 @@ explain extended
select a from t1 group by a having a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+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);
@@ -1093,7 +1095,7 @@ explain extended
select a from t1 group by a having a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+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);
@@ -1148,21 +1150,21 @@ drop table t2;
create table t1 (a1 int key);
create table t2 (b1 int);
insert into t1 values (5);
-explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+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 b1 from t2 group by b1);
+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 b1 from t2 group by b1);
+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 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
-select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+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;
@@ -1170,7 +1172,7 @@ 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 t2 system NULL NULL NULL NULL 0 const row not found
+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
@@ -1200,7 +1202,7 @@ insert into t1 values ('aa', 'aaaa');
explain select a,b from t1 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+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)";
@@ -1229,7 +1231,7 @@ WHERE (t1i) IN (
SELECT t2i
FROM t2
WHERE (t2i) IN (
-SELECT t3i
+SELECT max(t3i)
FROM t3
GROUP BY t3i
)
@@ -1237,8 +1239,8 @@ GROUP BY t3i
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using temporary
+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,
@@ -1337,17 +1339,20 @@ DROP TABLE t1,t2,t3;
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 SUBQUERY 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
#
@@ -1371,7 +1376,7 @@ WHERE t1.f1 IN (SELECT t1.pk FROM t1 ORDER BY t1.f1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t1 system NULL NULL NULL NULL 1
+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
@@ -1445,7 +1450,7 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
COUNT(*)
2
@@ -1469,7 +1474,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan
+2 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
@@ -1510,7 +1515,7 @@ insert into t1 values (0),(1),(2);
explain select a, a in (select a from t1) from t0;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 3
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+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
@@ -1725,8 +1730,90 @@ 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 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+Warnings:
+Note 1003 select 8 AS `a` from dual 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;
# 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';
@@ -1737,7 +1824,7 @@ insert into t1 values (0),(1),(2);
explain select a, a in (select a from t1) from t0;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 3
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+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
@@ -1769,7 +1856,7 @@ EXPLAIN
SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 system NULL NULL NULL NULL 1
+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
@@ -1777,7 +1864,7 @@ EXPLAIN
SELECT SUM(c1) c1_sum FROM t1 WHERE c1 IN (SELECT c2 FROM t2) HAVING c1_sum;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 system NULL NULL NULL NULL 1
+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;
@@ -1796,7 +1883,7 @@ 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 SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found
+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
@@ -1805,7 +1892,7 @@ 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 SUBQUERY t3 system NULL NULL NULL NULL 0 const row not found
+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
@@ -1847,7 +1934,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition
+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
@@ -1892,7 +1979,7 @@ 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 SUBQUERY t1 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
@@ -1909,7 +1996,7 @@ 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 SUBQUERY t1 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
@@ -1938,7 +2025,7 @@ SELECT (f1, f2, f3) NOT IN
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 SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using filesort
+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;
@@ -1961,7 +2048,7 @@ 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
+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';
@@ -1989,7 +2076,7 @@ FROM t1
WHERE (a, b) NOT IN (SELECT a, b FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
SELECT *
FROM t1
WHERE (a, b) NOT IN (SELECT a, b FROM t2);
@@ -2001,7 +2088,7 @@ SELECT a, b, (a, b) NOT IN (SELECT a, b FROM t2) as sq
FROM t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
diff --git a/mysql-test/r/subselect_mat_cost.result b/mysql-test/r/subselect_mat_cost.result
index 5531c7e107f..6cf5062c61b 100644
--- a/mysql-test/r/subselect_mat_cost.result
+++ b/mysql-test/r/subselect_mat_cost.result
@@ -65,7 +65,7 @@ Name LIKE 'L%') AND
surfacearea > 1000000;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL Name,SurfaceArea NULL NULL NULL 239 Using where
-2 SUBQUERY City ALL Population,Country NULL NULL NULL 4080 Using where
+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
@@ -134,7 +134,7 @@ City.name LIKE '%Island%');
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
1 PRIMARY City ref Country Country 3 world.Country.Code 18 Using where
-2 SUBQUERY CountryLanguage ALL Percentage,Language NULL NULL NULL 984 Using where
+2 MATERIALIZED CountryLanguage ALL Percentage,Language NULL NULL NULL 984 Using where
SELECT *
FROM Country, City
WHERE City.Country = Country.Code AND
@@ -204,7 +204,7 @@ OR
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL PRIMARY,SurfaceArea NULL NULL NULL 239 Using where
1 PRIMARY City ref Country Country 3 world.Country.Code 18 Using where
-3 SUBQUERY CountryLanguage index PRIMARY,Language PRIMARY 33 NULL 984 Using index
+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
@@ -233,7 +233,7 @@ where City.id not in (select capital from Country
where capital is not null and population < 100000);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY City index NULL PRIMARY 4 NULL 4080 Using where; Using index
-2 SUBQUERY Country ALL NULL NULL NULL NULL 239 Using where
+2 MATERIALIZED Country ALL NULL NULL NULL NULL 239 Using where
Q2.2e:
Countries that speak French, but do not speak English
@@ -247,7 +247,7 @@ AND CountryLanguage.Language = 'French'
AND Code = Country;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage ref PRIMARY,Language Language 30 const 20 Using index condition
-1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index condition
+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
@@ -286,8 +286,8 @@ AND (CountryLanguage.Language = 'French' OR CountryLanguage.Language = 'Spanish'
AND Code = Country;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage range PRIMARY,Language Language 30 NULL 45 Using index condition; Using where; Rowid-ordered scan
-1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index condition
-2 SUBQUERY CountryLanguage ref PRIMARY,Language Language 30 const 47 Using index condition
+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')
@@ -371,8 +371,8 @@ FROM City LEFT JOIN Country ON (Country = Code)
HAVING City.Name LIKE "Santa%");
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage index NULL PRIMARY 33 NULL 984 Using where; Using index
-2 SUBQUERY City ALL NULL NULL NULL NULL 4080
-2 SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using index
+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
@@ -399,10 +399,10 @@ WHERE Code = Country GROUP BY Code)
order by Country;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY CountryLanguage index NULL PRIMARY 33 NULL 984 Using where; Using index
-3 SUBQUERY CountryLanguage index PRIMARY PRIMARY 33 NULL 984 Using index; Using temporary
-3 SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index
-2 SUBQUERY CountryLanguage index PRIMARY PRIMARY 33 NULL 984 Using index; Using temporary
-2 SUBQUERY Country eq_ref PRIMARY PRIMARY 3 world.CountryLanguage.Country 1 Using index
+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
@@ -429,7 +429,7 @@ capital is null);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL NULL NULL NULL NULL 239 Using where
1 PRIMARY City eq_ref PRIMARY PRIMARY 4 world.Country.Capital 1 Using where
-2 SUBQUERY City index NULL CityName 35 NULL 4080 Using index
+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
@@ -450,7 +450,7 @@ WHERE Country.Code NOT IN
(SELECT Country FROM City GROUP BY Name HAVING COUNT(Name) = 1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY Country ALL NULL NULL NULL NULL 239 Using where
-2 SUBQUERY City ALL NULL NULL NULL NULL 4080 Using temporary
+2 MATERIALIZED City ALL NULL NULL NULL NULL 4080 Using temporary
SELECT Name
FROM Country
WHERE Country.Code NOT IN
@@ -480,7 +480,7 @@ from City
where City.population > 10000000;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY City range Population Population 5 NULL 4 Using index condition; Rowid-ordered scan
-2 SUBQUERY Country ALL NULL NULL NULL NULL 239 Using where
+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;
@@ -512,9 +512,9 @@ FROM City JOIN Country ON City.Country = Country.Code
GROUP BY City.Name
HAVING City.Name IN (select Name from Country where population < 1000000);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY City ALL Country NULL NULL NULL 4080 Using temporary; Using filesort
-1 PRIMARY Country eq_ref PRIMARY PRIMARY 3 world.City.Country 1 Using index
-2 SUBQUERY Country ALL Name NULL NULL NULL 239 Using where
+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
diff --git a/mysql-test/r/subselect_mat_cost_bugs.result b/mysql-test/r/subselect_mat_cost_bugs.result
index 9ba318a58f1..96f904c722c 100644
--- a/mysql-test/r/subselect_mat_cost_bugs.result
+++ b/mysql-test/r/subselect_mat_cost_bugs.result
@@ -141,14 +141,14 @@ CREATE TABLE t3 ( f2 varchar(1)) ;
EXPLAIN SELECT f2 FROM t3 WHERE (
SELECT MAX( pk ) FROM t1
WHERE EXISTS (
-SELECT DISTINCT f1
-FROM t2
+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
+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
@@ -156,6 +156,8 @@ drop table t1, t2, t3;
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);
@@ -171,6 +173,7 @@ 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
@@ -179,6 +182,8 @@ 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
@@ -206,6 +211,7 @@ field1
Warnings:
Warning 1292 Truncated incorrect INTEGER value: 'f'
Warning 1292 Truncated incorrect INTEGER value: 'd'
+set optimizer_switch=@tmp_optimizer_switch;
drop table t1,t2;
#
# LP BUG#718578 Yet another Assertion `!table ||
@@ -257,8 +263,8 @@ 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 SUBQUERY alias1 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+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
@@ -277,8 +283,8 @@ 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 SUBQUERY alias1 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY alias2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
+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
@@ -383,14 +389,14 @@ set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_
explain select * from t1 where c1 = 'a2' and (c1, c2) not in (select * from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
index b9705205999..8ac856857eb 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -3,11 +3,14 @@ select @@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)
@@ -206,6 +209,8 @@ 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
@@ -214,6 +219,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
@@ -1375,7 +1381,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 0 0.00 Using index condition
+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`))
@@ -1400,7 +1406,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
@@ -1663,7 +1669,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`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);
@@ -1671,7 +1677,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`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);
@@ -1687,7 +1693,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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);
@@ -1703,7 +1709,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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
@@ -2980,9 +2986,9 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `tes
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
+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') 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));
@@ -4358,6 +4364,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');
@@ -4389,6 +4398,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -4514,18 +4524,21 @@ 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 t1 ALL NULL NULL NULL NULL 2 100.00
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,<exists>(select 1 from `test`.`t1` group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1)))))
-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 `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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <expr_cache><1>(<in_optimizer>(1,<exists>(select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1)))))
+Note 1003 select 1 AS `1` from `test`.`t1` where <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.
@@ -4601,6 +4614,32 @@ 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';
+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;
End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
@@ -4843,8 +4882,6 @@ SELECT * FROM t1
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
pk a
1 10
-3 30
-2 20
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
INSERT INTO t1 VALUES (1,NULL), (9,NULL);
@@ -5553,8 +5590,8 @@ explain SELECT * FROM ot1,ot4
WHERE (ot1.a,ot4.a) IN (SELECT it2.a,it3.a
FROM it2,it3);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY ot1 ALL NULL NULL NULL NULL 2 Start temporary
-1 PRIMARY it2 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
+1 PRIMARY it2 ALL NULL NULL NULL NULL 4 Using where; Start temporary; Using join buffer (flat, BNL join)
1 PRIMARY it3 ALL NULL NULL NULL NULL 6 Using join buffer (flat, BNL join)
1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; End temporary; Using join buffer (flat, BNL join)
DROP TABLE IF EXISTS ot1, ot4, it2, it3;
@@ -5597,16 +5634,19 @@ 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 Start temporary
-1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; Using join buffer (flat, BNL join)
-1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index; End temporary
+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
@@ -5614,18 +5654,21 @@ DROP table t1,t2;
#
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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+2 DEPENDENT 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:
@@ -5837,6 +5880,8 @@ 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
@@ -5851,9 +5896,9 @@ 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;
End of 5.3 tests
-End of 5.5 tests.
#
# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
#
@@ -5886,10 +5931,13 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (a INT, b INT, INDEX (a));
INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ref a a 5 const 1
+set optimizer_switch=@tmp_optimizer_switch;
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
@@ -5968,7 +6016,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
-2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
DROP TABLE t1,t2;
#
# lp:826279: assertion failure with GROUP BY a result of subquery
@@ -6030,9 +6078,216 @@ set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquer
select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select 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;
+# 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
index 91878c5dec5..518f9366b80 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -1,9 +1,12 @@
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)
@@ -202,6 +205,8 @@ 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
@@ -210,6 +215,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
@@ -1371,7 +1377,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 0 0.00 Using index condition
+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`))
@@ -1396,7 +1402,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
@@ -1497,10 +1503,10 @@ a
explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 100.00 Using index
-2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+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`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where ((`test`.`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
@@ -1659,7 +1665,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`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);
@@ -1667,7 +1673,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`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);
@@ -1683,7 +1689,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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);
@@ -1699,7 +1705,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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
@@ -2976,9 +2982,9 @@ Note 1003 select `test`.`t1`.`one` AS `one`,`test`.`t1`.`two` AS `two` from `tes
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
+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`,<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));
@@ -4354,6 +4360,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');
@@ -4385,6 +4394,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -4510,18 +4520,21 @@ 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 t1 ALL NULL NULL NULL NULL 2 100.00
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select 1 from `test`.`t1` group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1))))
-EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a);
+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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
Warnings:
-Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (1 = <ref_null_helper>(1))))
+Note 1003 select 1 AS `1` from `test`.`t1` where <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.
@@ -4597,6 +4610,32 @@ 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';
+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;
End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
@@ -4839,8 +4878,6 @@ SELECT * FROM t1
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
pk a
1 10
-3 30
-2 20
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
INSERT INTO t1 VALUES (1,NULL), (9,NULL);
@@ -5593,16 +5630,19 @@ 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 t2 index NULL PRIMARY 4 NULL 3 Using index
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
@@ -5610,18 +5650,21 @@ DROP table t1,t2;
#
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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+2 DEPENDENT 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:
@@ -5833,6 +5876,8 @@ 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
@@ -5847,9 +5892,9 @@ 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;
End of 5.3 tests
-End of 5.5 tests.
#
# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
#
@@ -5882,10 +5927,13 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (a INT, b INT, INDEX (a));
INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ref a a 5 const 1
+set optimizer_switch=@tmp_optimizer_switch;
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
@@ -5964,7 +6012,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
-2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
DROP TABLE t1,t2;
#
# lp:826279: assertion failure with GROUP BY a result of subquery
@@ -6026,6 +6074,212 @@ set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquer
select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select 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;
+# 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
index fb04fa2e7bc..320e51da39e 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -2,11 +2,14 @@ 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)
@@ -205,6 +208,8 @@ 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
@@ -213,6 +218,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
@@ -1374,7 +1380,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 0 0.00 Using index condition
+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`))
@@ -1399,7 +1405,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
@@ -1662,7 +1668,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`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);
@@ -1670,7 +1676,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`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);
@@ -1686,7 +1692,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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);
@@ -1702,7 +1708,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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
@@ -2974,15 +2980,15 @@ explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FR
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 10 func,func 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 9 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` 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
+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`,<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));
@@ -3564,7 +3570,7 @@ 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 23 test.t1.a,test.t1.b 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+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
@@ -3576,7 +3582,7 @@ 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 23 test.t1.a,test.t1.b 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+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);
@@ -4360,6 +4366,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');
@@ -4391,6 +4400,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -4516,20 +4526,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 5 const 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
Warnings:
-Note 1003 select 1 AS `1` from <materialize> (select 1 from `test`.`t1` group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`1` = 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 <subquery2> const distinct_key distinct_key 5 const 1 100.00
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00
-1 PRIMARY <subquery2> const distinct_key distinct_key 4 const 1 100.00
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
+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 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a`) join `test`.`t1` where (`<subquery2>`.`1` = 1)
+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.
@@ -4605,6 +4618,32 @@ 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';
+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;
End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
@@ -4847,8 +4886,6 @@ SELECT * FROM t1
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
pk a
1 10
-3 30
-2 20
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
INSERT INTO t1 VALUES (1,NULL), (9,NULL);
@@ -5560,8 +5597,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY ot1 ALL NULL NULL NULL NULL 2
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 24 Using where
1 PRIMARY ot4 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join)
-2 SUBQUERY it2 ALL NULL NULL NULL NULL 4
-2 SUBQUERY it3 ALL NULL NULL NULL NULL 6 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
@@ -5602,16 +5639,19 @@ 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 Start temporary
-1 PRIMARY t2 index NULL PRIMARY 4 NULL 3 Using index; Using join buffer (flat, BNL join)
-1 PRIMARY it eq_ref PRIMARY PRIMARY 4 test.t1.pk 1 Using index; End temporary
+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
@@ -5619,18 +5659,21 @@ DROP table t1,t2;
#
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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+2 DEPENDENT 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:
@@ -5842,6 +5885,8 @@ 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
@@ -5856,9 +5901,9 @@ 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;
End of 5.3 tests
-End of 5.5 tests.
#
# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
#
@@ -5891,10 +5936,13 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (a INT, b INT, INDEX (a));
INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ref a a 5 const 1
+set optimizer_switch=@tmp_optimizer_switch;
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
@@ -5973,7 +6021,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
-2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
DROP TABLE t1,t2;
#
# lp:826279: assertion failure with GROUP BY a result of subquery
@@ -6035,9 +6083,216 @@ set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquer
select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select 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;
+# 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
index 071c58eb6e4..0c41f612ae9 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -1,9 +1,12 @@
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)
@@ -202,6 +205,8 @@ 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
@@ -210,6 +215,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
@@ -904,7 +910,7 @@ a t1.a in (select t2.a from t2)
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 SUBQUERY t2 index a a 5 NULL 3 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');
@@ -918,8 +924,8 @@ a t1.a in (select t2.a from t2,t3 where t3.a=t2.a)
explain extended SELECT t1.a, t1.a in (select t2.a from t2,t3 where t3.a=t2.a) FROM t1;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
-2 SUBQUERY t2 index a a 5 NULL 3 100.00 Using index
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+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;
@@ -1371,7 +1377,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 0 0.00 Using index condition
+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`))
@@ -1396,7 +1402,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
@@ -1434,7 +1440,7 @@ a
explain extended select * from t2 where t2.a in (select a from t1);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
-2 SUBQUERY t1 index PRIMARY PRIMARY 4 NULL 4 100.00 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);
@@ -1444,7 +1450,7 @@ a
explain extended select * from t2 where t2.a in (select a from t1 where t1.b <> 30);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
-2 SUBQUERY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where
+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);
@@ -1454,8 +1460,8 @@ a
explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL PRIMARY 4 NULL 4 100.00 Using where; Using index
-2 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 3 100.00 Using index
-2 SUBQUERY t1 ALL PRIMARY NULL NULL NULL 4 100.00 Using where; Using join buffer (flat, BNL join)
+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;
@@ -1497,10 +1503,10 @@ a
explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t2 index NULL a 5 NULL 4 100.00 Using where; Using index
-2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 100.00 Using index
-2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 100.00 Using where; Using index; Using join buffer (flat, BNL join)
+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`.`t3`.`a` = `test`.`t1`.`b`) and (<cache>(`test`.`t2`.`a`) = `test`.`t1`.`a`)))))
+Note 1003 select `test`.`t2`.`a` AS `a` from `test`.`t2` where <expr_cache><`test`.`t2`.`a`>(<in_optimizer>(`test`.`t2`.`a`,<exists>(select `test`.`t1`.`a` from `test`.`t1` join `test`.`t3` where ((`test`.`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
@@ -1605,25 +1611,25 @@ 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 SUBQUERY t2 index s1 s1 6 NULL 2 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 SUBQUERY t2 index s1 s1 6 NULL 2 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 SUBQUERY t2 index s1 s1 6 NULL 2 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 SUBQUERY t2 index s1 s1 6 NULL 2 50.00 Using where; 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;
@@ -1659,7 +1665,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select NULL from `test`.`t2` group by 1) > <cache>(`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);
@@ -1667,7 +1673,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00 Using where
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select NULL from `test`.`t2` group by 1) <= <cache>(`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);
@@ -1683,7 +1689,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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);
@@ -1699,7 +1705,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t3 ALL NULL NULL NULL NULL 3 100.00
2 SUBQUERY t2 system NULL NULL NULL NULL 0 0.00 const row not found
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select NULL from `test`.`t2` group by 1) <= NULL)))
+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
@@ -1878,7 +1884,7 @@ id text
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 SUBQUERY t1 range PRIMARY PRIMARY 4 NULL 7 100.00 Using where; Using index
+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);
@@ -2964,21 +2970,21 @@ one two test
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 SUBQUERY t2 ALL NULL NULL NULL NULL 9 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`,<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 SUBQUERY t2 ALL NULL NULL NULL NULL 9 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 SUBQUERY t2 ALL NULL NULL NULL NULL 9 100.00 Using where; Using temporary
+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') group by `test`.`t2`.`one`,`test`.`t2`.`two` ), <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`
+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));
@@ -3159,7 +3165,7 @@ 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 SUBQUERY t1 index a a 5 NULL 5 Using index
+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
@@ -3559,7 +3565,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+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
@@ -3570,7 +3576,7 @@ EXPLAIN
SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9 Using where
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+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);
@@ -4354,6 +4360,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');
@@ -4364,7 +4373,7 @@ CREATE INDEX I2 ON t1 (b);
EXPLAIN SELECT a,b FROM t1 WHERE b IN (SELECT a FROM t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t1 index I1 I1 2 NULL 2 Using index
+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));
@@ -4374,17 +4383,18 @@ CREATE INDEX I2 ON t2 (b);
EXPLAIN SELECT a,b FROM t2 WHERE b IN (SELECT a FROM t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t2 index I1 I1 4 NULL 2 Using index
+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 SUBQUERY t1 index I1 I1 2 NULL 2 Using where; Using index
+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
@@ -4510,18 +4520,21 @@ 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 t1 ALL NULL NULL NULL NULL 2 100.00
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary
+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 1 from `test`.`t1` group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `<subquery2>`.`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 `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 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary
+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 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` ), <primary_index_lookup>(1 in <temporary table> on distinct_key where ((1 = `<subquery2>`.`1`))))))
+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.
@@ -4597,6 +4610,32 @@ 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';
+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;
End of 5.0 tests.
create table t_out (subcase char(3),
a1 char(2), b1 char(2), c1 char(2));
@@ -4839,8 +4878,6 @@ SELECT * FROM t1
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
pk a
1 10
-3 30
-2 20
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
INSERT INTO t1 VALUES (1,NULL), (9,NULL);
@@ -5551,8 +5588,8 @@ 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 SUBQUERY it2 ALL NULL NULL NULL NULL 4
-2 SUBQUERY it3 ALL NULL NULL NULL NULL 6 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
@@ -5593,16 +5630,19 @@ 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 SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using index
-2 SUBQUERY it index PRIMARY PRIMARY 4 NULL 3 Using index; Using join buffer (flat, BNL join)
+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
@@ -5610,18 +5650,21 @@ DROP table t1,t2;
#
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 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 Using temporary
+2 DEPENDENT 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:
@@ -5833,6 +5876,8 @@ 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
@@ -5840,16 +5885,16 @@ 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 SUBQUERY t3 ALL NULL NULL NULL NULL 2
+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;
End of 5.3 tests
-End of 5.5 tests.
#
# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
#
@@ -5882,10 +5927,13 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (a INT, b INT, INDEX (a));
INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 2
2 DERIVED t1 ref a a 5 const 1
+set optimizer_switch=@tmp_optimizer_switch;
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
@@ -5964,7 +6012,7 @@ WHERE f1_key != table2.f1_key AND f1_key >= table1.f1 );
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY table1 ALL NULL NULL NULL NULL 2
1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer (flat, BNL join)
-2 DEPENDENT SUBQUERY t2 range f1_key f1_key 4 NULL 6 Range checked for each record (index map: 0x1); Using temporary
+2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index
DROP TABLE t1,t2;
#
# lp:826279: assertion failure with GROUP BY a result of subquery
@@ -6026,6 +6074,213 @@ set @@optimizer_switch='in_to_exists=on,semijoin=off,materialization=off,subquer
select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select a from t1 where a in (select 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;
+# 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_partial_match.result b/mysql-test/r/subselect_partial_match.result
index dddf5e2d8d6..4e37b831326 100644
--- a/mysql-test/r/subselect_partial_match.result
+++ b/mysql-test/r/subselect_partial_match.result
@@ -74,7 +74,7 @@ EXPLAIN
SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 3
+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
@@ -82,7 +82,7 @@ EXPLAIN
SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 3
+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';
@@ -90,7 +90,7 @@ EXPLAIN
SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 3
+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
@@ -98,7 +98,7 @@ EXPLAIN
SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 3
+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;
@@ -129,7 +129,7 @@ EXPLAIN
SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
@@ -137,7 +137,7 @@ EXPLAIN
SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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';
@@ -145,7 +145,7 @@ EXPLAIN
SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
@@ -153,7 +153,7 @@ EXPLAIN
SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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;
@@ -188,7 +188,7 @@ EXPLAIN
SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
@@ -196,7 +196,7 @@ EXPLAIN
SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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';
@@ -204,7 +204,7 @@ EXPLAIN
SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
@@ -212,7 +212,7 @@ EXPLAIN
SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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;
@@ -247,7 +247,7 @@ EXPLAIN
SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
@@ -255,7 +255,7 @@ EXPLAIN
SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
@@ -264,7 +264,7 @@ EXPLAIN
SELECT t1.*, (a1, a2, a3) IN (select * from t2) as in_res from t1;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
@@ -272,7 +272,7 @@ EXPLAIN
SELECT * from t1 where (a1, a2, a3) NOT IN (select * from t2);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+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
@@ -766,14 +766,17 @@ CREATE TABLE t2 (b1 int DEFAULT NULL, b2 int DEFAULT NULL);
INSERT INTO t2 VALUES (6,NULL);
INSERT INTO t2 VALUES (NULL,0);
set @@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 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
+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
@@ -784,7 +787,7 @@ insert into t1 values (NULL, 'a21'), (NULL, 'a22');
explain select * from t1 where (a1, a2) not in (select a1, a2 from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Using where
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+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;
@@ -818,8 +821,8 @@ SELECT t3.d , t2.c
FROM t3 LEFT JOIN t2 ON t3.a = t2.a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
-2 SUBQUERY t3 system NULL NULL NULL NULL 1
-2 SUBQUERY t2 system NULL NULL NULL NULL 1
+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 (
@@ -857,7 +860,7 @@ 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
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT b, a FROM t2);
c
0
@@ -866,7 +869,7 @@ 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
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
SELECT * FROM t1 WHERE (6, 4 ) NOT IN (SELECT a, b FROM t2);
c
0
@@ -902,7 +905,7 @@ set @@optimizer_switch='in_to_exists=off,materialization=on,partial_match_rowid_
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
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3
SELECT * FROM t2 WHERE ( 3 , 1 ) NOT IN ( SELECT f1 , f2 FROM t1 );
f3
5
@@ -948,4 +951,35 @@ 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
index af29a0332f3..8fcedc5807f 100644
--- a/mysql-test/r/subselect_sj.result
+++ b/mysql-test/r/subselect_sj.result
@@ -4,6 +4,9 @@ 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);
@@ -79,7 +82,7 @@ id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
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 SUBQUERY t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
+2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on((<in_optimizer>(`test`.`B`.`A`,`test`.`B`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`B`.`A` in <temporAry tABle> on distinct_key where ((`test`.`B`.`A` = `<suBquery2>`.`pk`))))) And (`test`.`A`.`A` = `test`.`t1`.`A`))) where 1
t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
@@ -88,7 +91,7 @@ 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 SUBQUERY t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
+2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on((<in_optimizer>(`test`.`t2`.`A`,`test`.`t2`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t2`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t2`.`A` = `<suBquery2>`.`pk`))))) And (`test`.`t2`.`A` = `test`.`t1`.`A`))) where 1
we shouldn't flatten if we're going to get a join of > MAX_TABLES.
@@ -726,8 +729,8 @@ 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 SUBQUERY it1 index NULL int_key 4 NULL 2 Using index
-2 SUBQUERY it2 ALL int_key,datetime_key NULL NULL NULL 20 Using where
+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
#
@@ -800,7 +803,7 @@ EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk
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 13 func,func 1 100.00
-2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Rowid-ordered scan
+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);
@@ -967,11 +970,11 @@ SELECT `varchar_key` , `varchar_nokey`
FROM t1
WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
-2 SUBQUERY t1 ALL varchar_key NULL NULL NULL 15 100.00 Using where
+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`.`t1`.`varchar_key` < 'n') xor `test`.`t1`.`pk`))
+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 (
@@ -1052,8 +1055,8 @@ 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 14 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 14 func 1
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 5 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+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
@@ -1242,8 +1245,8 @@ 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; Start temporary
-1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; End temporary
+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
@@ -1275,8 +1278,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 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 5 func 1
-2 SUBQUERY C ALL NULL NULL NULL NULL 3
-3 SUBQUERY D ALL NULL NULL NULL NULL 3
+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
@@ -1291,7 +1294,7 @@ 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 SUBQUERY <derived3> system NULL NULL NULL NULL 1
+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
@@ -1396,8 +1399,8 @@ explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.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 SUBQUERY t1 ALL NULL NULL NULL NULL 2
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 Using where
+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;
@@ -1449,8 +1452,8 @@ set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+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
@@ -1508,8 +1511,8 @@ explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+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
@@ -1526,8 +1529,8 @@ explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where
+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
@@ -1721,10 +1724,10 @@ INSERT INTO t4 VALUES (0),(NULL);
explain
SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Start temporary
+1 PRIMARY 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; End temporary
+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
@@ -1782,9 +1785,9 @@ INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
explain
SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY 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; End temporary
+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
@@ -1872,6 +1875,8 @@ INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
(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,
@@ -1887,10 +1892,10 @@ alias1.c IN (SELECT SQ3_alias1.b
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
LIMIT 100;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Start temporary
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20
1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
-1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where
+1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Start temporary
1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary
2 DERIVED t2 ALL NULL NULL NULL NULL 20
create table t3 as
@@ -1907,6 +1912,7 @@ 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;
@@ -1942,45 +1948,18 @@ DROP TABLE t1, t2, t4, t5;
#
# BUG#861147: Assertion `fixed == 1' failed in Item_func_eq::val_int() with semijoin + materialization + max_join_size
#
-CREATE TABLE t1 ( f2 int) ;
-CREATE TABLE t2 ( f1 int, f3 int, f4 varchar(3), f5 varchar(35)) ;
-INSERT INTO t2 VALUES (4057,9,'USA','Visalia'),(3993,11,'USA','Waco'),
-(3948,14,'USA','Warren'),(3813,57,'USA','Washington'),
-(4010,11,'USA','Waterbury'),(4017,11,'USA','West Covina'),
-(4004,11,'USA','West Valley City'),(4033,10,'USA','Westminster'),
-(3842,34,'USA','Wichita'),(4018,10,'USA','Wichita Falls'),
-(3899,19,'USA','Winston-Salem'),(3914,17,'USA','Worcester'),
-(3888,20,'USA','Yonkers');
-CREATE TABLE t3 ( f3 int, f4 varchar(3)) ;
-INSERT INTO t3 VALUES (86,'USA');
-CREATE TABLE t4 ( f3 int, f4 varchar(3), f5 varchar(52)) ;
-INSERT INTO t4 VALUES (0,'RUS','Belorussian'),(0,'USA','Portuguese');
-CREATE TABLE t5 ( f2 int) ;
-CREATE TABLE t6 ( f4 varchar(3));
-INSERT INTO t6 VALUES ('RUS'),('USA');
+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';
-SELECT *
-FROM t1
-WHERE ( 1 , 3 ) IN (
-SELECT t2.f1 , MAX( t3.f3 )
-FROM t2
-JOIN t3
-WHERE t3.f4 IN (
-SELECT t4.f5
-FROM t4
-STRAIGHT_JOIN t5
-WHERE t4.f4 < t2.f5
-)
-) AND ( 'p' , 'k' ) IN (
-SELECT f4 , f4 FROM t6
-);
+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,t2,t3,t4,t5,t6;
+drop table t1;
#
# BUG#877288: Wrong result with semijoin + materialization + multipart key
#
@@ -1997,8 +1976,8 @@ SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 13 Using where
-2 SUBQUERY t2 ref b b 4 test.t3.a 1 Using index
+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
@@ -2050,8 +2029,8 @@ set optimizer_switch='semijoin_with_cache=on';
explain
select * from t1 where t1.a in (select t2.a from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+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
@@ -2060,8 +2039,8 @@ set optimizer_switch='semijoin_with_cache=off';
explain
select * from t1 where t1.a in (select t2.a from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary
+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
@@ -2101,4 +2080,103 @@ 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 5 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;
set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/r/subselect_sj2.result b/mysql-test/r/subselect_sj2.result
index c95aaab1c13..85a3b6971bd 100644
--- a/mysql-test/r/subselect_sj2.result
+++ b/mysql-test/r/subselect_sj2.result
@@ -1,7 +1,10 @@
set @subselect_sj2_tmp= @@optimizer_switch;
set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
-drop table if exists t0, t1, t2, t3;
+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);
@@ -48,7 +51,7 @@ explain select * from t2 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
1 PRIMARY t2 ref b b 5 test.t1.a 2
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 Using where
select * from t2 where b in (select a from t1);
a b
1 1
@@ -66,9 +69,9 @@ 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 5 func 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
+1 PRIMARY t3 ref b b 5 test.t1.a 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 Using where
select * from t3 where b in (select a from t1);
a b pk1 pk2 pk3
1 1 1 1 1
@@ -94,7 +97,7 @@ 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 <subquery2> ALL distinct_key NULL NULL NULL 10
1 PRIMARY t3 ref b b 5 test.t0.a 1
-2 SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
+2 MATERIALIZED t0 ALL NULL NULL NULL NULL 10 Using where
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
@@ -145,7 +148,7 @@ 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 SUBQUERY it ALL NULL NULL NULL NULL 22
+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);
@@ -178,7 +181,7 @@ 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 5 func 1
-2 SUBQUERY it ALL NULL NULL NULL NULL 32
+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);
@@ -213,7 +216,7 @@ 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 SUBQUERY it ALL NULL NULL NULL NULL 22
+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);
@@ -246,7 +249,7 @@ 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 5 func 1
-2 SUBQUERY it ALL NULL NULL NULL NULL 52
+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);
@@ -287,9 +290,9 @@ from t0 where a in
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 10
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1 Using where
-2 SUBQUERY t1 index a a 5 NULL 10 Using where; Using index
-2 SUBQUERY t2 ref a a 5 test.t1.a 1 Using index
-2 SUBQUERY t3 ref a a 5 test.t1.a 1 Using index
+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,
@@ -328,8 +331,8 @@ 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
-1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; End 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 (
@@ -367,7 +370,7 @@ 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 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
+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);
@@ -602,7 +605,7 @@ select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 10 Using index
+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);
@@ -716,7 +719,7 @@ 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 5 func 1
-2 SUBQUERY t3 index a a 5 NULL 30000 Using index
+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
@@ -872,10 +875,10 @@ 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 5 func 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t4 ALL NULL NULL NULL NULL 2
+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);
diff --git a/mysql-test/r/subselect_sj2_jcl6.result b/mysql-test/r/subselect_sj2_jcl6.result
index 48797f5cdd6..b179a735f20 100644
--- a/mysql-test/r/subselect_sj2_jcl6.result
+++ b/mysql-test/r/subselect_sj2_jcl6.result
@@ -7,10 +7,15 @@ 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';
-drop table if exists t0, t1, t2, t3;
+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);
@@ -57,7 +62,7 @@ explain select * from t2 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
1 PRIMARY t2 ref b b 5 test.t1.a 2 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 Using where
select * from t2 where b in (select a from t1);
a b
1 1
@@ -75,9 +80,9 @@ 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 5 func 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
+1 PRIMARY t3 ref b b 5 test.t1.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 Using where
select * from t3 where b in (select a from t1);
a b pk1 pk2 pk3
1 1 1 1 1
@@ -102,8 +107,8 @@ 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 <subquery2> ALL distinct_key NULL NULL NULL 10
-1 PRIMARY t3 ref b b 5 test.t0.a 1 (flat, BKA join); Key-ordered Rowid-ordered scan
-2 SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
+1 PRIMARY t3 ref b b 5 test.t0.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+2 MATERIALIZED t0 ALL NULL NULL NULL NULL 10 Using where
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
@@ -124,8 +129,9 @@ 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)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
+2 MATERIALIZED t2 index b b 5 NULL 20 Using index
select * from t1;
a b
1 1
@@ -154,7 +160,7 @@ 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 SUBQUERY it ALL NULL NULL NULL NULL 22 Using where
+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);
@@ -187,7 +193,7 @@ 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 5 func 1
-2 SUBQUERY it ALL NULL NULL NULL NULL 32
+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);
@@ -222,7 +228,7 @@ 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 SUBQUERY it ALL NULL NULL NULL NULL 22 Using where
+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);
@@ -255,7 +261,7 @@ 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 5 func 1
-2 SUBQUERY it ALL NULL NULL NULL NULL 52
+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);
@@ -296,9 +302,9 @@ from t0 where a in
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 10
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1 Using where
-2 SUBQUERY t1 index a a 5 NULL 10 Using where; Using index
-2 SUBQUERY t2 ref a a 5 test.t1.a 1 Using index
-2 SUBQUERY t3 ref a a 5 test.t1.a 1 Using index
+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,
@@ -337,8 +343,8 @@ 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; 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; End temporary; Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan
+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 (
@@ -376,7 +382,7 @@ 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 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
+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);
@@ -613,7 +619,7 @@ select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
1 PRIMARY t2 hash_ALL NULL #hash#$hj 5 test.t1.a 3 Using where; Using join buffer (flat, BNLH join)
-2 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 10 Using index
+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);
@@ -727,7 +733,7 @@ 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 5 func 1
-2 SUBQUERY t3 index a a 5 NULL 30000 Using index
+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
@@ -883,10 +889,10 @@ 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 5 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)
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t4 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);
@@ -896,8 +902,97 @@ DROP VIEW v1;
DROP TABLE t1,t2,t3,t4;
# 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
+1 PRIMARY t1 ref b b 4 test.t3.b 1 Using index
+1 PRIMARY t4 ALL NULL NULL NULL NULL 2 Using where; FirstMatch(t2)
+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 t1 ALL NULL NULL NULL NULL 2
+1 PRIMARY t3 eq_ref PRIMARY PRIMARY 4 test.t4.b 1 Using where; FirstMatch(t4)
+SELECT * FROM t1, t2 WHERE b IN (SELECT a FROM t3, t4 WHERE b = pk);
+pk a b
+1 6 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 5 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 5 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 1
+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
index 1b7fccf924c..0284bab0972 100644
--- a/mysql-test/r/subselect_sj2_mat.result
+++ b/mysql-test/r/subselect_sj2_mat.result
@@ -3,7 +3,10 @@ set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
set @subselect_sj2_tmp= @@optimizer_switch;
set optimizer_switch='semijoin=on,firstmatch=on,loosescan=on';
set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
-drop table if exists t0, t1, t2, t3;
+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);
@@ -50,7 +53,7 @@ explain select * from t2 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
1 PRIMARY t2 ref b b 5 test.t1.a 2
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 Using where
select * from t2 where b in (select a from t1);
a b
1 1
@@ -68,9 +71,9 @@ 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 5 func 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 3
+1 PRIMARY t3 ref b b 5 test.t1.a 1
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 3 Using where
select * from t3 where b in (select a from t1);
a b pk1 pk2 pk3
1 1 1 1 1
@@ -96,7 +99,7 @@ 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 <subquery2> ALL distinct_key NULL NULL NULL 10
1 PRIMARY t3 ref b b 5 test.t0.a 1
-2 SUBQUERY t0 ALL NULL NULL NULL NULL 10 Using where
+2 MATERIALIZED t0 ALL NULL NULL NULL NULL 10 Using where
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
@@ -147,7 +150,7 @@ 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 SUBQUERY it ALL NULL NULL NULL NULL 22
+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);
@@ -180,7 +183,7 @@ 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 5 func 1
-2 SUBQUERY it ALL NULL NULL NULL NULL 32
+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);
@@ -215,7 +218,7 @@ 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 SUBQUERY it ALL NULL NULL NULL NULL 22
+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);
@@ -248,7 +251,7 @@ 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 5 func 1
-2 SUBQUERY it ALL NULL NULL NULL NULL 52
+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);
@@ -289,9 +292,9 @@ from t0 where a in
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 10
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 func 1 Using where
-2 SUBQUERY t1 index a a 5 NULL 10 Using where; Using index
-2 SUBQUERY t2 ref a a 5 test.t1.a 1 Using index
-2 SUBQUERY t3 ref a a 5 test.t1.a 1 Using index
+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,
@@ -330,8 +333,8 @@ 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
-1 PRIMARY t3 eq_ref PRIMARY,Percentage PRIMARY 33 test.t1.Country,const 1 Using index condition; Using where; End 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 (
@@ -369,7 +372,7 @@ 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 SUBQUERY t2 ALL CountryCode NULL NULL NULL 545 Using where
+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);
@@ -604,7 +607,7 @@ select * from t1 left join t2 on (t2.a= t1.a and t2.a in (select pk from t3));
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3
1 PRIMARY t2 ALL NULL NULL NULL NULL 3 Using where
-2 SUBQUERY t3 index PRIMARY PRIMARY 4 NULL 10 Using index
+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);
@@ -718,7 +721,7 @@ 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 5 func 1
-2 SUBQUERY t3 index a a 5 NULL 30000 Using index
+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
@@ -874,10 +877,10 @@ 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 5 func 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 1 Using where
1 PRIMARY <derived3> ALL NULL NULL NULL NULL 2
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t4 ALL NULL NULL NULL NULL 2
+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);
@@ -891,3 +894,25 @@ 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;
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
index b697939d4bc..88acba0ebea 100644
--- a/mysql-test/r/subselect_sj_jcl6.result
+++ b/mysql-test/r/subselect_sj_jcl6.result
@@ -9,12 +9,17 @@ 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);
@@ -90,7 +95,7 @@ id select_type tABle type possiBle_keys key key_len ref rows filtered ExtrA
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
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 SUBQUERY t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
+2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`A`.`A` AS `A`,`test`.`A`.`B` AS `B`,`test`.`B`.`A` AS `A`,`test`.`B`.`B` AS `B` from `test`.`t1` left join (`test`.`t2` `A` join `test`.`t2` `B`) on((<in_optimizer>(`test`.`B`.`A`,`test`.`B`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`B`.`A` in <temporAry tABle> on distinct_key where ((`test`.`B`.`A` = `<suBquery2>`.`pk`))))) And (`test`.`A`.`A` = `test`.`t1`.`A`))) where 1
t2 should be wrapped into OJ-nest, so we have "t1 LJ (t2 J t10)"
@@ -99,7 +104,7 @@ 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 SUBQUERY t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
+2 MATERIALIZED t10 index PRIMARY PRIMARY 4 NULL 10 100.00 Using index
Warnings:
Note 1003 select `test`.`t1`.`A` AS `A`,`test`.`t1`.`B` AS `B`,`test`.`t2`.`A` AS `A`,`test`.`t2`.`B` AS `B` from `test`.`t1` left join `test`.`t2` on((<in_optimizer>(`test`.`t2`.`A`,`test`.`t2`.`A` in ( <mAteriAlize> (select `test`.`t10`.`pk` from `test`.`t10` ), <primAry_index_lookup>(`test`.`t2`.`A` in <temporAry tABle> on distinct_key where ((`test`.`t2`.`A` = `<suBquery2>`.`pk`))))) And (`test`.`t2`.`A` = `test`.`t1`.`A`))) where 1
we shouldn't flatten if we're going to get a join of > MAX_TABLES.
@@ -737,8 +742,8 @@ 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 SUBQUERY it1 index NULL int_key 4 NULL 2 Using index
-2 SUBQUERY it2 ALL int_key,datetime_key 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
#
@@ -811,7 +816,7 @@ EXPLAIN EXTENDED SELECT pk FROM t1 WHERE (a, b) IN (SELECT a, b FROM t2 WHERE pk
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 13 func,func 1 100.00
-2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 100.00 Using index condition; Rowid-ordered scan
+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);
@@ -978,11 +983,11 @@ SELECT `varchar_key` , `varchar_nokey`
FROM t1
WHERE `varchar_nokey` < 'n' XOR `pk` ) ;
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 18 100.00
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 8 func,func 1 100.00
-2 SUBQUERY t1 ALL varchar_key NULL NULL NULL 15 100.00 Using where
+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`.`t1`.`varchar_key` < 'n') xor `test`.`t1`.`pk`))
+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 (
@@ -1063,8 +1068,8 @@ 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 14 func 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 14 func 1
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 5 Using where
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 Using where
+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
@@ -1253,8 +1258,8 @@ 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; Start temporary
-1 PRIMARY B index NULL PRIMARY 4 NULL 3 Using index; End temporary; Using join buffer (flat, BNL join)
+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
@@ -1286,8 +1291,8 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 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 5 func 1
-2 SUBQUERY C ALL NULL NULL NULL NULL 3
-3 SUBQUERY D ALL NULL NULL NULL NULL 3
+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
@@ -1302,7 +1307,7 @@ 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 SUBQUERY <derived3> system NULL NULL NULL NULL 1
+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
@@ -1407,8 +1412,8 @@ explain select * from t3 where t3.b in (select t2.b from t1 left join t2 on t1.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 SUBQUERY t1 ALL NULL NULL NULL NULL 2
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 2 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;
@@ -1460,8 +1465,8 @@ set optimizer_switch='firstmatch=off,loosescan=off,materialization=off';
explain
select * from t0 where a in (select t1.a from t1 left join t2 on t1.a=t2.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY 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
@@ -1519,8 +1524,8 @@ explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY 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
@@ -1537,8 +1542,8 @@ explain
select * from t0
where a in (select t1.a from t1 left join (t3 join t2 on t3.b=t2.b) on t1.a=t3.a);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 2 Start temporary
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY 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
@@ -1639,12 +1644,13 @@ CREATE VIEW v4 AS SELECT DISTINCT f2 FROM t4 ;
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 t2 ALL NULL NULL NULL NULL 2 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 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`.`t1`.`f2` = `test`.`t2`.`f2`) and (`test`.`t3`.`f1` = `test`.`t1`.`f1`) and (`test`.`t4`.`f2` = `test`.`t2`.`f3`))
+Note 1003 select `test`.`t1`.`f1` AS `f1`,`test`.`t1`.`f2` AS `f2`,`test`.`t2`.`f3` AS `f3`,`test`.`t3`.`f3` AS `f3` from `test`.`t1` semi join (`test`.`t4`) join `test`.`t2` join `test`.`t3` where ((`test`.`t1`.`f2` = `test`.`t2`.`f2`) and (`test`.`t3`.`f1` = `test`.`t1`.`f1`))
SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE t2.f3 IN (SELECT * FROM t4);
f1 f2 f3 f3
2 0 0 0
@@ -1732,10 +1738,10 @@ INSERT INTO t4 VALUES (0),(NULL);
explain
SELECT * FROM t1 NATURAL LEFT JOIN (t2, t3) WHERE IFNULL(t2.f3,'foo') IN (SELECT * FROM t4);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Start temporary
+1 PRIMARY 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; End temporary; 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
@@ -1793,9 +1799,9 @@ INSERT INTO t3 VALUES (6,5),(6,2),(8,0),(9,1),(6,5);
explain
SELECT * FROM t1, t2 WHERE (t2.a , t1.b) IN (SELECT a, b FROM t3);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 Start temporary
+1 PRIMARY 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; End temporary; Using join buffer (incremental, 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
@@ -1883,6 +1889,8 @@ INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
(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,
@@ -1898,10 +1906,10 @@ alias1.c IN (SELECT SQ3_alias1.b
FROM t2 AS SQ3_alias1 STRAIGHT_JOIN t2 AS SQ3_alias2)
LIMIT 100;
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20 Start temporary
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 20
1 PRIMARY alias2 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join)
1 PRIMARY t2 ALL NULL NULL NULL NULL 20 Using join buffer (incremental, BNL join)
-1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Using join buffer (incremental, BNL join)
+1 PRIMARY SQ3_alias1 ALL NULL NULL NULL NULL 20 Using where; Start temporary; Using join buffer (incremental, BNL join)
1 PRIMARY SQ3_alias2 index NULL PRIMARY 4 NULL 20 Using index; End temporary; Using join buffer (incremental, BNL join)
2 DERIVED t2 ALL NULL NULL NULL NULL 20
create table t3 as
@@ -1918,6 +1926,7 @@ 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;
@@ -1953,45 +1962,18 @@ DROP TABLE t1, t2, t4, t5;
#
# BUG#861147: Assertion `fixed == 1' failed in Item_func_eq::val_int() with semijoin + materialization + max_join_size
#
-CREATE TABLE t1 ( f2 int) ;
-CREATE TABLE t2 ( f1 int, f3 int, f4 varchar(3), f5 varchar(35)) ;
-INSERT INTO t2 VALUES (4057,9,'USA','Visalia'),(3993,11,'USA','Waco'),
-(3948,14,'USA','Warren'),(3813,57,'USA','Washington'),
-(4010,11,'USA','Waterbury'),(4017,11,'USA','West Covina'),
-(4004,11,'USA','West Valley City'),(4033,10,'USA','Westminster'),
-(3842,34,'USA','Wichita'),(4018,10,'USA','Wichita Falls'),
-(3899,19,'USA','Winston-Salem'),(3914,17,'USA','Worcester'),
-(3888,20,'USA','Yonkers');
-CREATE TABLE t3 ( f3 int, f4 varchar(3)) ;
-INSERT INTO t3 VALUES (86,'USA');
-CREATE TABLE t4 ( f3 int, f4 varchar(3), f5 varchar(52)) ;
-INSERT INTO t4 VALUES (0,'RUS','Belorussian'),(0,'USA','Portuguese');
-CREATE TABLE t5 ( f2 int) ;
-CREATE TABLE t6 ( f4 varchar(3));
-INSERT INTO t6 VALUES ('RUS'),('USA');
+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';
-SELECT *
-FROM t1
-WHERE ( 1 , 3 ) IN (
-SELECT t2.f1 , MAX( t3.f3 )
-FROM t2
-JOIN t3
-WHERE t3.f4 IN (
-SELECT t4.f5
-FROM t4
-STRAIGHT_JOIN t5
-WHERE t4.f4 < t2.f5
-)
-) AND ( 'p' , 'k' ) IN (
-SELECT f4 , f4 FROM t6
-);
+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,t2,t3,t4,t5,t6;
+drop table t1;
#
# BUG#877288: Wrong result with semijoin + materialization + multipart key
#
@@ -2008,8 +1990,8 @@ SELECT * FROM t1 WHERE (a) IN (SELECT a FROM t2 JOIN t3 ON b = a);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 9
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t3 ALL NULL NULL NULL NULL 13 Using where
-2 SUBQUERY t2 ref b b 4 test.t3.a 1 Using index
+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
@@ -2061,8 +2043,8 @@ set optimizer_switch='semijoin_with_cache=on';
explain
select * from t1 where t1.a in (select t2.a from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary; Using join buffer (flat, BNL join)
+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
@@ -2071,8 +2053,8 @@ set optimizer_switch='semijoin_with_cache=off';
explain
select * from t1 where t1.a in (select t2.a from t2);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 4 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 6 Using where; End temporary
+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
@@ -2112,6 +2094,105 @@ 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 5 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;
set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
@@ -2133,8 +2214,8 @@ explain
SELECT * FROM t0 WHERE t0.a IN
(SELECT t1.a FROM t1, t2 WHERE t2.a=t0.a AND t1.b=t2.b);
id select_type table type possible_keys key key_len ref rows Extra
-1 PRIMARY t0 ALL NULL NULL NULL NULL 5 Using where; Start temporary
-1 PRIMARY t1 ref a a 5 test.t0.a 1 Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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);
@@ -2166,9 +2247,9 @@ 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 Start temporary
-1 PRIMARY t3 ALL d NULL NULL NULL 5 Range checked for each record (index map: 0x2)
-1 PRIMARY t2 hash_ALL PRIMARY #hash#PRIMARY 4 test.t3.b 4 End temporary; Using join buffer (flat, BNLH join)
+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
@@ -2181,9 +2262,9 @@ 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 Start temporary
-1 PRIMARY t3 ALL d NULL NULL NULL 5 Range checked for each record (index map: 0x2)
-1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 test.t3.b 1 End temporary; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan
+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
@@ -2197,5 +2278,7 @@ DROP TABLE t1,t2,t3;
set join_cache_level=default;
show variables like 'join_cache_level';
Variable_name Value
-join_cache_level 1
+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
index fe34b4e2851..ee8a365327c 100644
--- a/mysql-test/r/subselect_sj_mat.result
+++ b/mysql-test/r/subselect_sj_mat.result
@@ -2,6 +2,8 @@ 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;
@@ -46,7 +48,7 @@ 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 9 func 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 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` semi join (`test`.`t2`) where ((`test`.`t2`.`b1` > '0'))
select * from t1 where a1 in (select b1 from t2 where b1 > '0');
@@ -56,11 +58,11 @@ a1 a2
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
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 test.t1.a1 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 9 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 <materialize> (select `test`.`t2`.`b1` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where (`<subquery2>`.`b1` = `test`.`t1`.`a1`)
+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
@@ -68,11 +70,11 @@ a1 a2
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
-1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 18 test.t1.a1,test.t1.a2 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 18 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 <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`<subquery2>`.`b2` = `test`.`t1`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1`.`a1`))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `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
@@ -82,7 +84,7 @@ select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' gr
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 18 test.t1.a1,test.t1.a2 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using temporary
Warnings:
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1`,min(`test`.`t2`.`b2`) from `test`.`t2` where (`test`.`t2`.`b1` > '0') group by `test`.`t2`.`b1`) join `test`.`t1` where ((`<subquery2>`.`min(b2)` = `test`.`t1`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, min(b2) from t2 where b1 > '0' group by b1);
@@ -101,14 +103,14 @@ a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
explain extended
-select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+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 <subquery2> ALL distinct_key # NULL # 3 100.00 #
-1 PRIMARY t1i ref it1i1,it1i3 # 9 # 1 100.00 #
-2 SUBQUERY t2i range it2i1,it2i3 # 9 # 3 100.00 #
+1 PRIMARY t1i index it1i1,it1i3 # 18 # 3 100.00 #
+1 PRIMARY <subquery2> eq_ref distinct_key # 9 # 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 `test`.`t2i`.`b1` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where (`test`.`t1i`.`a1` = `<subquery2>`.`b1`)
-select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+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
@@ -124,14 +126,14 @@ a1 a2
1 - 01 2 - 01
1 - 02 2 - 02
explain extended
-select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+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 SUBQUERY t2i range it2i1,it2i3 # # # 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 <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`<subquery2>`.`b2` = `test`.`t1i`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1i`.`a1`))
-select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`<subquery2>`.`max(b2)` = `test`.`t1i`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1i`.`a1`))
+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
@@ -140,7 +142,7 @@ select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0'
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 SUBQUERY t2i range it2i1,it2i3 # # # 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 <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1i` where ((`<subquery2>`.`min(b2)` = `test`.`t1i`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1i`.`a1`))
select * from t1i where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
@@ -152,7 +154,7 @@ 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 18 test.t1.a1,test.t1.a2 1 100.00
-2 SUBQUERY t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
+2 MATERIALIZED t2i range NULL it2i3 9 NULL 3 100.00 Using index for group-by
Warnings:
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,max(`test`.`t2i`.`b2`) from `test`.`t2i` group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`<subquery2>`.`max(b2)` = `test`.`t1`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, max(b2) from t2i group by b1);
@@ -164,12 +166,12 @@ 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 18 test.t1.a1,test.t1.a2 1
-2 SUBQUERY t2i range NULL it2i3 9 NULL 3 Using index for group-by
+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 18 test.t1.a1,test.t1.a2 1
-2 SUBQUERY t2i range NULL it2i3 9 NULL 3 Using index for group-by
+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
@@ -184,7 +186,7 @@ select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' g
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 18 test.t1.a1,test.t1.a2 1 100.00
-2 SUBQUERY t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
+2 MATERIALIZED t2i range it2i1,it2i3 it2i3 18 NULL 3 100.00 Using where; Using index for group-by
Warnings:
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2i`.`b1`,min(`test`.`t2i`.`b2`) from `test`.`t2i` where (`test`.`t2i`.`b1` > '0') group by `test`.`t2i`.`b1`) join `test`.`t1` where ((`<subquery2>`.`min(b2)` = `test`.`t1`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, min(b2) from t2i where b1 > '0' group by b1);
@@ -232,7 +234,7 @@ 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 18 test.t1.a1,test.t1.a2 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 5 100.00
Warnings:
Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` order by `test`.`t2`.`b1`,`test`.`t2`.`b2`) join `test`.`t1` where ((`<subquery2>`.`b2` = `test`.`t1`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1`.`a1`))
select * from t1 where (a1, a2) in (select b1, b2 from t2 order by b1, b2);
@@ -244,7 +246,7 @@ 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 18 test.t1i.a1,test.t1i.a2 1 100.00
-2 SUBQUERY t2i index NULL it2i3 18 NULL 5 100.00 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 <materialize> (select `test`.`t2i`.`b1`,`test`.`t2i`.`b2` from `test`.`t2i` order by `test`.`t2i`.`b1`,`test`.`t2i`.`b2`) join `test`.`t1i` where ((`<subquery2>`.`b2` = `test`.`t1i`.`a2`) and (`<subquery2>`.`b1` = `test`.`t1i`.`a1`))
select * from t1i where (a1, a2) in (select b1, b2 from t2i order by b1, b2);
@@ -297,11 +299,11 @@ where (a1, a2) in (select b1, b2 from t2 where b1 > '0') and
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 <subquery2> eq_ref distinct_key distinct_key 18 func,func 1 100.00
1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 18 func,func 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-3 SUBQUERY t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 18 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`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (`test`.`t2`.`b1` > '0') and (`test`.`t3`.`c2` > '0'))
select * from t1
@@ -317,14 +319,12 @@ 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 it1i1,it1i2,it1i3 # # # 3 100.00 #
-1 PRIMARY <subquery2> eq_ref distinct_key # # # 1 100.00 #
-1 PRIMARY <subquery3> eq_ref distinct_key # # # 1 100.00 #
-2 SUBQUERY t2i index it2i1,it2i2,it2i3 # # # 5 100.00 #
-3 SUBQUERY t2i index it2i1,it2i2,it2i3 # # # 5 100.00 #
-3 SUBQUERY t3i index it3i1,it3i2,it3i3 # # # 4 75.00 #
+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`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0'))
+Note 1003 select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b2` = `test`.`t2i`.`b2`) and (`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0'))
select * from t1i
where (a1, a2) in (select b1, b2 from t2i where b1 > '0') and
(a1, a2) in (select c1, c2 from t3i
@@ -341,13 +341,13 @@ b2 in (select c2 from t3 where c2 LIKE '%03')) and
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 <subquery2> eq_ref distinct_key distinct_key 18 func,func 1 100.00
1 PRIMARY <subquery5> eq_ref distinct_key distinct_key 18 func,func 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where
-5 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-5 SUBQUERY t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-3 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
+1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 18 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`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3`.`c2` > '0'))
select * from t1
@@ -366,16 +366,16 @@ 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 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00
1 PRIMARY <subquery5> eq_ref distinct_key distinct_key 18 func,func 1 100.00
-5 SUBQUERY t3c ALL NULL NULL NULL NULL 4 100.00 Using where
-5 SUBQUERY t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
-4 SUBQUERY t3b ALL NULL NULL NULL NULL 4 100.00 Using where
+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`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b2` = `test`.`t3c`.`c2`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b1` = `test`.`t3c`.`c1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3c`.`c2` > '0'))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b2` = `test`.`t3c`.`c2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b1` = `test`.`t3c`.`c1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3c`.`c2` > '0'))
select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 t3a where c1 = a1) or
@@ -399,22 +399,21 @@ 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 <subquery2> ALL distinct_key # # # 5 0.00 #
-1 PRIMARY t3 ALL NULL # # # 4 100.00 #
1 PRIMARY t1 ALL NULL # # # 3 100.00 #
-1 PRIMARY t2i ref it2i1,it2i2,it2i3 # # # 2 100.00 #
-2 SUBQUERY t2 ALL NULL # # # 5 100.00 #
-4 SUBQUERY t3 ALL NULL # # # 4 100.00 #
-3 SUBQUERY t3 ALL NULL # # # 4 100.00 #
-7 UNION t1i index it1i1,it1i2,it1i3 # # # 3 100.00 #
-7 UNION <subquery8> eq_ref distinct_key # # # 1 100.00 #
-7 UNION <subquery9> eq_ref distinct_key # # # 1 100.00 #
-8 SUBQUERY t2i index it2i1,it2i2,it2i3 # # # 5 100.00 #
-9 SUBQUERY t2i index it2i1,it2i2,it2i3 # # # 5 100.00 #
-9 SUBQUERY t3i index it3i1,it3i2,it3i3 # # # 4 75.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 <materialize> (select `test`.`t2`.`b1`,`test`.`t2`.`b2` from `test`.`t2` where (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) group by `test`.`t2`.`b1`,`test`.`t2`.`b2`) semi join (`test`.`t2i` join `test`.`t3`) join `test`.`t1` where ((`test`.`t3`.`c2` = `<subquery2>`.`b2`) and (`test`.`t1`.`a2` = `<subquery2>`.`b2`) and (`test`.`t2i`.`b2` = `<subquery2>`.`b2`) and (`test`.`t3`.`c1` = `<subquery2>`.`b1`) and (`test`.`t1`.`a1` = `<subquery2>`.`b1`) and (`test`.`t2i`.`b1` = `<subquery2>`.`b1`) and (`<subquery2>`.`b2` > '0'))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0')))
+Note 1003 (select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3`) where ((`test`.`t2i`.`b2` = `test`.`t3`.`c2`) and (`test`.`t2i`.`b1` = `test`.`t3`.`c1`) and (<expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%02') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery3>`.`c2`)))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3`.`c2` from `test`.`t3` where (`test`.`t3`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))) and (`test`.`t3`.`c2` > '0'))) union (select `test`.`t1i`.`a1` AS `a1`,`test`.`t1i`.`a2` AS `a2` from `test`.`t1i` semi join (`test`.`t2i`) semi join (`test`.`t2i` join `test`.`t3i`) where ((`test`.`t1i`.`a2` = `test`.`t2i`.`b2`) and (`test`.`t3i`.`c2` = `test`.`t2i`.`b2`) and (`test`.`t2i`.`b2` = `test`.`t2i`.`b2`) and (`test`.`t1i`.`a1` = `test`.`t2i`.`b1`) and (`test`.`t3i`.`c1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` = `test`.`t2i`.`b1`) and (`test`.`t2i`.`b1` > '0') and (`test`.`t2i`.`b2` > '0')))
(select * from t1
where (a1, a2) in (select b1, b2 from t2
where b2 in (select c2 from t3 where c2 LIKE '%02') or
@@ -438,8 +437,8 @@ 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 18 func,func 1 100.00
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-4 SUBQUERY t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+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
@@ -462,8 +461,8 @@ 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 18 func,func 1 100.00
-4 SUBQUERY t3 ALL NULL NULL NULL NULL 4 100.00 Using where
-4 SUBQUERY t2i index it2i1,it2i2,it2i3 it2i3 18 NULL 5 80.00 Using where; Using index; Using join buffer (flat, BNL join)
+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
@@ -505,16 +504,16 @@ 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; Start temporary
-1 PRIMARY t2i ref it2i1,it2i2,it2i3 it2i3 18 test.t1.a1,test.t1.a2 2 100.00 Using index
-1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join)
+1 PRIMARY t1 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
+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)
-4 SUBQUERY t3b ALL NULL NULL NULL NULL 4 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` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2i`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t3c`.`c2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t3c`.`c1` = `test`.`t1`.`a1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))))
+Note 1003 select `test`.`t1`.`a1` AS `a1`,`test`.`t1`.`a2` AS `a2` from `test`.`t1` semi join (`test`.`t2`) semi join (`test`.`t2i` join `test`.`t3` `t3c`) where ((`test`.`t2`.`b2` = `test`.`t1`.`a2`) and (`test`.`t2i`.`b2` = `test`.`t1`.`a2`) and (`test`.`t3c`.`c2` = `test`.`t1`.`a2`) and (`test`.`t2`.`b1` = `test`.`t1`.`a1`) and (`test`.`t2i`.`b1` = `test`.`t1`.`a1`) and (`test`.`t3c`.`c1` = `test`.`t1`.`a1`) and (<expr_cache><`test`.`t2`.`b2`,`test`.`t1`.`a1`>(<in_optimizer>(`test`.`t2`.`b2`,<exists>(select `test`.`t3a`.`c2` from `test`.`t3` `t3a` where ((`test`.`t3a`.`c1` = `test`.`t1`.`a1`) and (<cache>(`test`.`t2`.`b2`) = `test`.`t3a`.`c2`))))) or <expr_cache><`test`.`t2`.`b2`>(<in_optimizer>(`test`.`t2`.`b2`,`test`.`t2`.`b2` in ( <materialize> (select `test`.`t3b`.`c2` from `test`.`t3` `t3b` where (`test`.`t3b`.`c2` like '%03') ), <primary_index_lookup>(`test`.`t2`.`b2` in <temporary table> on distinct_key where ((`test`.`t2`.`b2` = `<subquery4>`.`c2`))))))))
explain extended
select * from t1 where (a1, a2) in (select '1 - 01', '2 - 01');
id select_type table type possible_keys key key_len ref rows filtered Extra
@@ -617,8 +616,8 @@ 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; Start temporary
-1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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)
@@ -631,8 +630,8 @@ 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; Start temporary
-1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select left(`test`.`t1_16`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_16`.`a2`,7) AS `left(a2,7)` from `test`.`t1_16` semi join (`test`.`t2_16`) where ((`test`.`t2_16`.`b2` = `test`.`t1_16`.`a2`) and (`test`.`t2_16`.`b1` = `test`.`t1_16`.`a1`) and (`test`.`t1_16`.`a1` > '0'))
select left(a1,7), left(a2,7)
@@ -647,7 +646,7 @@ where a1 in (select substring(b1,1,16) from t2_16 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 20 func 1 100.00 Using where
-2 SUBQUERY t2_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` 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)
@@ -677,7 +676,7 @@ 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 261 test.t1_16.a1 1 100.00 Using where
-2 SUBQUERY t2_16 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -695,8 +694,8 @@ where (a1, a2) IN
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 Start temporary
-1 PRIMARY t1_16 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join)
+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)
@@ -732,8 +731,8 @@ 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; Start temporary
-1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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)
@@ -746,8 +745,8 @@ 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; Start temporary
-1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select left(`test`.`t1_512`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_512`.`a2`,7) AS `left(a2,7)` from `test`.`t1_512` semi join (`test`.`t2_512`) where ((`test`.`t2_512`.`b2` = `test`.`t1_512`.`a2`) and (`test`.`t2_512`.`b1` = `test`.`t1_512`.`a1`) and (`test`.`t1_512`.`a1` > '0'))
select left(a1,7), left(a2,7)
@@ -762,7 +761,7 @@ where a1 in (select substring(b1,1,512) from t2_512 where b1 > '0');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1_512 ALL NULL NULL NULL NULL 3 100.00
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 517 func 1 100.00 Using where
-2 SUBQUERY t2_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` 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)
@@ -777,7 +776,7 @@ 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 261 test.t1_512.a1 1 100.00 Using where
-2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -791,7 +790,7 @@ 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 261 test.t1_512.a1 1 100.00 Using where
-2 SUBQUERY t2_512 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -828,8 +827,8 @@ 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; Start temporary
-1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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)
@@ -842,8 +841,8 @@ 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; Start temporary
-1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t1_1024 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select left(`test`.`t1_1024`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1024`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1024` semi join (`test`.`t2_1024`) where ((`test`.`t2_1024`.`b2` = `test`.`t1_1024`.`a2`) and (`test`.`t2_1024`.`b1` = `test`.`t1_1024`.`a1`) and (`test`.`t1_1024`.`a1` > '0'))
select left(a1,7), left(a2,7)
@@ -856,8 +855,8 @@ 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 Start temporary
-1 PRIMARY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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)
@@ -872,7 +871,7 @@ 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 261 test.t1_1024.a1 1 100.00 Using where
-2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -886,7 +885,7 @@ 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 261 test.t1_1024.a1 1 100.00 Using where
-2 SUBQUERY t2_1024 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -923,8 +922,8 @@ 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; Start temporary
-1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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)
@@ -937,8 +936,8 @@ 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; Start temporary
-1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t1_1025 ALL NULL NULL NULL NULL 3 100.00 Using where
+1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select left(`test`.`t1_1025`.`a1`,7) AS `left(a1,7)`,left(`test`.`t1_1025`.`a2`,7) AS `left(a2,7)` from `test`.`t1_1025` semi join (`test`.`t2_1025`) where ((`test`.`t2_1025`.`b2` = `test`.`t1_1025`.`a2`) and (`test`.`t2_1025`.`b1` = `test`.`t1_1025`.`a1`) and (`test`.`t1_1025`.`a1` > '0'))
select left(a1,7), left(a2,7)
@@ -951,8 +950,8 @@ 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 Start temporary
-1 PRIMARY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+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)
@@ -967,7 +966,7 @@ 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 261 test.t1_1025.a1 1 100.00 Using where
-2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -981,7 +980,7 @@ 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 261 test.t1_1025.a1 1 100.00 Using where
-2 SUBQUERY t2_1025 ALL NULL NULL NULL NULL 3 100.00 Using filesort
+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)
@@ -1003,7 +1002,7 @@ 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 10 func,func 1 100.00
-2 SUBQUERY t2bit ALL NULL NULL NULL NULL 3 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)
@@ -1025,8 +1024,8 @@ 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 Start temporary
-1 PRIMARY t2bb ALL NULL NULL NULL NULL 3 100.00 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY t1bb ALL NULL NULL NULL NULL 3 100.00
+1 PRIMARY t2bb ALL NULL NULL NULL NULL 3 100.00 Using where; Start temporary; End temporary; Using join buffer (flat, BNL join)
Warnings:
Note 1003 select conv(`test`.`t1bb`.`a1`,10,2) AS `bin(a1)`,`test`.`t1bb`.`a2` AS `a2` from `test`.`t1bb` semi join (`test`.`t2bb`) where ((`test`.`t2bb`.`b2` = `test`.`t1bb`.`a2`) and (`test`.`t2bb`.`b1` = `test`.`t1bb`.`a1`))
select bin(a1), a2
@@ -1075,7 +1074,7 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 6 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` 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);
@@ -1090,7 +1089,7 @@ 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 ref it1a it1a 4 test.t2.c 2 100.00 Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 6 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` 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);
@@ -1105,7 +1104,7 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+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);
@@ -1118,7 +1117,7 @@ explain extended
select a from t1 group by a having a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+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);
@@ -1130,7 +1129,7 @@ explain extended
select a from t1 group by a having a in (select c from t2 where d >= 20);
id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY t1 index NULL it1a 4 NULL 7 100.00 Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 7 100.00 Using where
+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);
@@ -1185,22 +1184,22 @@ drop table t2;
create table t1 (a1 int key);
create table t2 (b1 int);
insert into t1 values (5);
-explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+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 5 const 1
-2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL no matching row in const table
-select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+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 b1 from t2 group by b1);
+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 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 0 const row not found
-select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+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;
@@ -1238,7 +1237,7 @@ explain select a,b from t1 where b in (select a from t1);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 3 func 1 Using where
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 2
+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)";
@@ -1267,17 +1266,17 @@ WHERE (t1i) IN (
SELECT t2i
FROM t2
WHERE (t2i) IN (
-SELECT t3i
+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 5 const 1 Start temporary
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; End temporary; Using join buffer (flat, BNL join)
+1 PRIMARY <subquery3> eq_ref distinct_key distinct_key 5 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 SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using temporary
+3 MATERIALIZED t3 ALL NULL NULL NULL NULL 2 Using temporary
DROP TABLE t1,t2,t3,t4;
CREATE TABLE t1 (
pk INTEGER AUTO_INCREMENT,
@@ -1376,17 +1375,20 @@ DROP TABLE t1,t2,t3;
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 SUBQUERY 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
#
@@ -1411,7 +1413,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system NULL NULL NULL NULL 1
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 4 const 1
1 PRIMARY t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join)
-2 SUBQUERY t1 system NULL NULL NULL NULL 1
+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
@@ -1485,7 +1487,7 @@ 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 SUBQUERY t2 ALL NULL NULL NULL NULL 2
+2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2
SELECT COUNT(*) FROM t1 WHERE (f1,f2) IN (SELECT f1,f2 FROM t2);
COUNT(*)
2
@@ -1509,7 +1511,7 @@ EXPLAIN SELECT pk FROM t1 WHERE (a) IN (SELECT a FROM t2 WHERE pk > 0);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 2
1 PRIMARY <subquery2> eq_ref distinct_key distinct_key 5 func 1
-2 SUBQUERY t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Rowid-ordered scan
+2 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
@@ -1550,7 +1552,7 @@ insert into t1 values (0),(1),(2);
explain select a, a in (select a from t1) from t0;
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t0 ALL NULL NULL NULL NULL 3
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 3
+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
@@ -1765,5 +1767,88 @@ 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 dual 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;
# 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
index 192c0812236..8df74536de7 100644
--- a/mysql-test/r/subselect_sj_nonmerged.result
+++ b/mysql-test/r/subselect_sj_nonmerged.result
@@ -10,7 +10,7 @@ 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 SUBQUERY t1 ALL NULL NULL NULL NULL 10
+2 MATERIALIZED t1 ALL NULL NULL NULL NULL 10
select * from t0 where a in (select max(a) from t1);
a
9
@@ -42,23 +42,26 @@ 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 Using where
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
-2 SUBQUERY 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)
# 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 Using where
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
-2 SUBQUERY 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)
+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 Using where
1 PRIMARY t3 eq_ref PRIMARY PRIMARY 8 <subquery2>.max(t2.a) 1 Using where; Using index
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using temporary
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using where
+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
@@ -67,8 +70,8 @@ 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 5 test.t4.a 1
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
-2 SUBQUERY 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)
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
@@ -77,10 +80,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 5 Using where
1 PRIMARY <subquery3> ALL distinct_key NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join)
1 PRIMARY t4 ref a a 10 <subquery2>.max(t2.a),<subquery3>.max(t2.a) 12
-3 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
-3 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 Using temporary
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 10 Using join buffer (flat, BNL join)
+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;
#
@@ -114,6 +117,6 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 1 Using where
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 SUBQUERY t0 ALL NULL NULL NULL NULL 10
+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/table_elim.result b/mysql-test/r/table_elim.result
index 4b4ea83fcce..9b2656c17e4 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;
@@ -586,3 +588,4 @@ id select_type table type possible_keys key key_len ref rows Extra
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/trigger.result b/mysql-test/r/trigger.result
index 22f1546d322..ef998abafcf 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -2218,3 +2218,47 @@ aaa
DROP TABLE t1;
End of 5.5 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_datetime.result b/mysql-test/r/type_datetime.result
index ff052101753..811fbacaf59 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -510,6 +510,8 @@ 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));
@@ -538,8 +540,8 @@ explain extended
select * from t1
where id in (select id from t1 as x1 where (t1.cur_date is null));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary
-1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary
+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; 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` semi join (`test`.`t1` `x1`) where ((`test`.`x1`.`id` = `test`.`t1`.`id`) and (`test`.`t1`.`cur_date` = 0))
@@ -550,14 +552,15 @@ explain extended
select * from t2
where id in (select id from t2 as x1 where (t2.cur_date is null));
id select_type table type possible_keys key key_len ref rows filtered Extra
-1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Start temporary
-1 PRIMARY x1 ALL NULL NULL NULL NULL 2 100.00 Using where; End temporary
+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; 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` 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,
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 047cfbe5342..6b6b5a2392c 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -1544,6 +1544,49 @@ select * from t1;
5.05 / 0.014
360.714286
DROP TABLE t1;
+#
+# Bug#12563865
+# ROUNDED,TMP_BUF,DECIMAL_VALUE STACK CORRUPTION IN ALL VERSIONS >=5.0
+#
+SELECT substring(('M') FROM (999999999999999999999999999999999999999999999999999999999999999999999999999999999)) AS foo;
+foo
+
+Warnings:
+Warning 1916 Got overflow when converting '999999999999999999999999999999999999999999999999999999999999999999999999999999999' to INT. Value truncated.
+Warning 1916 Got overflow when converting '999999999999999999999999999999999999999999999999999999999999999999999999999999999' to INT. Value truncated.
+SELECT min(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
+foo
+999999999999999999999999999999999999999999999999999999999999999999999999999999999
+SELECT multipolygonfromtext(('4294967294.1'),(999999999999999999999999999999999999999999999999999999999999999999999999999999999)) AS foo;
+foo
+NULL
+Warnings:
+Warning 1916 Got overflow when converting '999999999999999999999999999999999999999999999999999999999999999999999999999999999' to INT. Value truncated.
+SELECT convert((999999999999999999999999999999999999999999999999999999999999999999999999999999999), decimal(30,30)) AS foo;
+foo
+0.999999999999999999999999999999
+Warnings:
+Warning 1264 Out of range value for column 'foo' at row 1
+SELECT bit_xor(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
+foo
+9223372036854775807
+Warnings:
+Warning 1916 Got overflow when converting '999999999999999999999999999999999999999999999999999999999999999999999999999999999' to INT. Value truncated.
+SELECT -(999999999999999999999999999999999999999999999999999999999999999999999999999999999) AS foo;
+foo
+-999999999999999999999999999999999999999999999999999999999999999999999999999999999
+SELECT date_sub((999999999999999999999999999999999999999999999999999999999999999999999999999999999),
+interval ((SELECT date_add((0x77500000),
+interval ('Oml') second)))
+day_minute)
+AS foo;
+foo
+NULL
+Warnings:
+Warning 1292 Incorrect datetime value: '999999999999999999999999999999999999999999999999999999999999999999999999999999999'
+SELECT truncate(999999999999999999999999999999999999999999999999999999999999999999999999999999999, 28) AS foo;
+foo
+999999999999999999999999999999999999999999999999999999999999999999999999999999999
End of 5.0 tests
select cast(143.481 as decimal(4,1));
cast(143.481 as decimal(4,1))
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 93e84c731fe..1ac688787c6 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -876,6 +876,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
@@ -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/r/variables-notembedded.result b/mysql-test/r/variables-notembedded.result
index 59c25f3e8b3..75fd2430e4b 100644
--- a/mysql-test/r/variables-notembedded.result
+++ b/mysql-test/r/variables-notembedded.result
@@ -125,7 +125,7 @@ max_allowed_packet 2048
SHOW SESSION VARIABLES LIKE 'net_buffer_length';
Variable_name Value
net_buffer_length 4096
-ERROR 08S01: Got a packet bigger than 'max_allowed_packet' bytes
+Got one of the listed errors
SELECT LENGTH(a) FROM t1;
LENGTH(a)
SET GLOBAL max_allowed_packet=default;
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 36f96d8e8f8..a2d51f625c4 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -1575,11 +1575,9 @@ id select_type table type possible_keys key key_len ref rows Extra
SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE f1 = 0);
one
1
-1
SELECT 1 as 'one' FROM t1 GROUP BY @a:= (SELECT ROUND(f1) FROM t1 WHERE @a=f1);
one
1
-1
DROP TABLE t1;
set sql_buffer_result=0;
CREATE TABLE t1 AS SELECT @a:= CAST(1 AS UNSIGNED) AS a;
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index f48d65c2dc0..f2d3820ff58 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);
@@ -4567,3 +4569,4 @@ NULL NULL 1 0
NULL NULL 1 0
DROP VIEW v2;
DROP TABLE t1, t2, t3;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index 9a0408bc174..7b94bdccc6b 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -66,10 +66,12 @@ create view mysqltest.v1 (c,d) as select a+1,b+1 from mysqltest.t1;
create algorithm=temptable view mysqltest.v2 (c,d) as select a+1,b+1 from mysqltest.t1;
create view mysqltest.v3 (c,d) as select a+1,b+1 from mysqltest.t2;
create algorithm=temptable view mysqltest.v4 (c,d) as select a+1,b+1 from mysqltest.t2;
+create view mysqltest.v5 (c,d) as select a+1,b+1 from mysqltest.t1;
grant select on mysqltest.v1 to mysqltest_1@localhost;
grant select on mysqltest.v2 to mysqltest_1@localhost;
grant select on mysqltest.v3 to mysqltest_1@localhost;
grant select on mysqltest.v4 to mysqltest_1@localhost;
+grant show view on mysqltest.v5 to mysqltest_1@localhost;
select c from mysqltest.v1;
c
select c from mysqltest.v2;
@@ -78,6 +80,8 @@ select c from mysqltest.v3;
c
select c from mysqltest.v4;
c
+select c from mysqltest.v5;
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v5'
show columns from mysqltest.v1;
Field Type Null Key Default Extra
c bigint(12) YES NULL
@@ -102,16 +106,25 @@ explain select c from mysqltest.v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v4;
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v4'
+explain select c from mysqltest.v5;
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v5'
+show create view mysqltest.v5;
+View Create View character_set_client collation_connection
+v5 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v5` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
+explain select c from mysqltest.v1;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+show create view mysqltest.v1;
+ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+grant show view on mysqltest.v1 to mysqltest_1@localhost;
grant select on mysqltest.t1 to mysqltest_1@localhost;
explain select c from mysqltest.v1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
show create view mysqltest.v1;
-ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
explain select c from mysqltest.v2;
-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
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v2;
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v2'
explain select c from mysqltest.v3;
@@ -122,6 +135,11 @@ explain select c from mysqltest.v4;
ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v4;
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v4'
+explain select c from mysqltest.v5;
+ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'v5'
+show create view mysqltest.v5;
+View Create View character_set_client collation_connection
+v5 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v5` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
grant show view on mysqltest.* to mysqltest_1@localhost;
explain select c from mysqltest.v1;
id select_type table type possible_keys key key_len ref rows Extra
@@ -137,15 +155,12 @@ show create view mysqltest.v2;
View Create View character_set_client collation_connection
v2 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v2` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1` latin1 latin1_swedish_ci
explain select c from mysqltest.v3;
-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
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v3;
View Create View character_set_client collation_connection
v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci
explain select c from mysqltest.v4;
-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
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
show create view mysqltest.v4;
View Create View character_set_client collation_connection
v4 CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v4` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2` latin1 latin1_swedish_ci
@@ -947,6 +962,197 @@ DROP USER foo;
DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
+Bug #11765687/#58677:
+No privilege on table/view, but can know #rows / underlying table's name
+create database mysqltest1;
+create table mysqltest1.t1 (i int);
+create table mysqltest1.t2 (j int);
+create table mysqltest1.t3 (k int, secret int);
+create user alice@localhost;
+create user bob@localhost;
+create user cecil@localhost;
+create user dan@localhost;
+create user eugene@localhost;
+create user fiona@localhost;
+create user greg@localhost;
+create user han@localhost;
+create user inga@localhost;
+create user jamie@localhost;
+create user karl@localhost;
+create user lena@localhost;
+create user mhairi@localhost;
+create user noam@localhost;
+create user olga@localhost;
+create user pjotr@localhost;
+create user quintessa@localhost;
+grant all privileges on mysqltest1.* to alice@localhost with grant option;
+... as alice
+create view v1 as select * from t1;
+create view v2 as select * from v1, t2;
+create view v3 as select k from t3;
+grant select on mysqltest1.v1 to bob@localhost;
+grant show view on mysqltest1.v1 to cecil@localhost;
+grant select, show view on mysqltest1.v1 to dan@localhost;
+grant select on mysqltest1.t1 to dan@localhost;
+grant select on mysqltest1.* to eugene@localhost;
+grant select, show view on mysqltest1.v2 to fiona@localhost;
+grant select, show view on mysqltest1.v2 to greg@localhost;
+grant show view on mysqltest1.v1 to greg@localhost;
+grant select(k) on mysqltest1.t3 to han@localhost;
+grant select, show view on mysqltest1.v3 to han@localhost;
+grant select on mysqltest1.t1 to inga@localhost;
+grant select on mysqltest1.t2 to inga@localhost;
+grant select on mysqltest1.v1 to inga@localhost;
+grant select, show view on mysqltest1.v2 to inga@localhost;
+grant select on mysqltest1.t1 to jamie@localhost;
+grant select on mysqltest1.t2 to jamie@localhost;
+grant show view on mysqltest1.v1 to jamie@localhost;
+grant select, show view on mysqltest1.v2 to jamie@localhost;
+grant select on mysqltest1.t1 to karl@localhost;
+grant select on mysqltest1.t2 to karl@localhost;
+grant select, show view on mysqltest1.v1 to karl@localhost;
+grant select on mysqltest1.v2 to karl@localhost;
+grant select on mysqltest1.t1 to lena@localhost;
+grant select on mysqltest1.t2 to lena@localhost;
+grant select, show view on mysqltest1.v1 to lena@localhost;
+grant show view on mysqltest1.v2 to lena@localhost;
+grant select on mysqltest1.t1 to mhairi@localhost;
+grant select on mysqltest1.t2 to mhairi@localhost;
+grant select, show view on mysqltest1.v1 to mhairi@localhost;
+grant select, show view on mysqltest1.v2 to mhairi@localhost;
+grant select on mysqltest1.t1 to noam@localhost;
+grant select, show view on mysqltest1.v1 to noam@localhost;
+grant select, show view on mysqltest1.v2 to noam@localhost;
+grant select on mysqltest1.t2 to olga@localhost;
+grant select, show view on mysqltest1.v1 to olga@localhost;
+grant select, show view on mysqltest1.v2 to olga@localhost;
+grant select on mysqltest1.t1 to pjotr@localhost;
+grant select on mysqltest1.t2 to pjotr@localhost;
+grant select, show view on mysqltest1.v2 to pjotr@localhost;
+grant select, show view on mysqltest1.v1 to quintessa@localhost;
+... as bob
+select * from v1;
+i
+explain select * from v1;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as cecil
+select * from v1;
+ERROR 42000: SELECT command denied to user 'cecil'@'localhost' for table 'v1'
+explain select * from v1;
+ERROR 42000: SELECT command denied to user 'cecil'@'localhost' for table 'v1'
+... as dan
+select * from v1;
+i
+explain select * from v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
+... as eugene
+select * from v1;
+i
+explain select * from v1;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as fiona
+select * from v2;
+i j
+show create view v2;
+View Create View character_set_client collation_connection
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`alice`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `v1`.`i` AS `i`,`t2`.`j` AS `j` from (`v1` join `t2`) latin1 latin1_swedish_ci
+explain select * from t1;
+ERROR 42000: SELECT command denied to user 'fiona'@'localhost' for table 't1'
+explain select * from v1;
+ERROR 42000: SELECT command denied to user 'fiona'@'localhost' for table 'v1'
+explain select * from t2;
+ERROR 42000: SELECT command denied to user 'fiona'@'localhost' for table 't2'
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as greg
+select * from v2;
+i j
+explain select * from v1;
+ERROR 42000: SELECT command denied to user 'greg'@'localhost' for table 'v1'
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as han
+select * from t3;
+ERROR 42000: SELECT command denied to user 'han'@'localhost' for table 't3'
+explain select * from t3;
+ERROR 42000: SELECT command denied to user 'han'@'localhost' for table 't3'
+select k from t3;
+k
+explain select k from t3;
+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
+select * from v3;
+k
+explain select * from v3;
+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
+... as inga
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as jamie
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as karl
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as lena
+select * from v2;
+ERROR 42000: SELECT command denied to user 'lena'@'localhost' for table 'v2'
+explain select * from v2;
+ERROR 42000: SELECT command denied to user 'lena'@'localhost' for table 'v2'
+... as mhairi
+select * from v2;
+i j
+explain select * from v2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 system NULL NULL NULL NULL 0 const row not found
+1 SIMPLE t2 system NULL NULL NULL NULL 0 const row not found
+... as noam
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as olga
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as pjotr
+select * from v2;
+i j
+explain select * from v2;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as quintessa
+select * from v1;
+i
+explain select * from v1;
+ERROR HY000: EXPLAIN/SHOW can not be issued; lacking privileges for underlying table
+... as root again at last: clean-up time!
+drop user alice@localhost;
+drop user bob@localhost;
+drop user cecil@localhost;
+drop user dan@localhost;
+drop user eugene@localhost;
+drop user fiona@localhost;
+drop user greg@localhost;
+drop user han@localhost;
+drop user inga@localhost;
+drop user jamie@localhost;
+drop user karl@localhost;
+drop user lena@localhost;
+drop user mhairi@localhost;
+drop user noam@localhost;
+drop user olga@localhost;
+drop user pjotr@localhost;
+drop user quintessa@localhost;
+drop database mysqltest1;
End of 5.0 tests.
DROP VIEW IF EXISTS v1;
DROP TABLE IF EXISTS t1;
diff --git a/mysql-test/std_data/bug887051.txt b/mysql-test/std_data/bug887051.txt
new file mode 100644
index 00000000000..a1df5f35bb1
--- /dev/null
+++ b/mysql-test/std_data/bug887051.txt
@@ -0,0 +1,2 @@
+saved1
+saved2
diff --git a/mysql-test/std_data/checkDBI_DBD-mysql.pl b/mysql-test/std_data/checkDBI_DBD-mysql.pl
index f001e471081..d62d2f8bfc0 100644
--- a/mysql-test/std_data/checkDBI_DBD-mysql.pl
+++ b/mysql-test/std_data/checkDBI_DBD-mysql.pl
@@ -1,6 +1,6 @@
#!/usr/bin/perl
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
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 904b14c06b5..07543e0c8c4 100644
--- a/mysql-test/suite/engines/funcs/r/de_calendar_range.result
+++ b/mysql-test/suite/engines/funcs/r/de_calendar_range.result
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1,t2,t3;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
@@ -89,3 +90,4 @@ c1
2007-02-16 12:10:34
2007-02-17 13:10:34
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 7479cf3ea0b..9c56e23574d 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NULL, c3 DATE NULL, PRIMARY KEY(c1), UNIQUE(c2));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'4 04:01:01'),NOW());
@@ -128,3 +129,4 @@ c1 c2 c3
2003 2001 2000
2004 2000 2000
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 763e9f564c6..47355681eae 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
@@ -82,3 +83,4 @@ c1
2000
2011
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 3f2b1546995..f8bff355901 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
@@ -87,3 +88,4 @@ c1
1999
2000
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 3f2b1546995..f8bff355901 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
@@ -87,3 +88,4 @@ c1
1999
2000
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 154c44426bc..5c4307158fa 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL UNIQUE);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
@@ -82,3 +83,4 @@ c1
2000
2011
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 6c395c5f6b9..9f6a205530c 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL UNIQUE);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
@@ -87,3 +88,4 @@ c1
1999
2000
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 58802aab0b2..5469527b762 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL UNIQUE);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
@@ -81,3 +82,4 @@ c1
1999
2000
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 f2cafdfce52..d7dfc9d794c 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NOT NULL, c3 DATE NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -144,3 +145,4 @@ c1 c2 c3
2011 2011 2000
2011 2011 2011
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 b630d3f519f..d71af8d6375 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NOT NULL, c3 DATE NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -147,3 +148,4 @@ c1 c2 c3
1999 2000 1999
2000 1999 1999
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 b630d3f519f..d71af8d6375 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NOT NULL, c3 DATE NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -147,3 +148,4 @@ c1 c2 c3
1999 2000 1999
2000 1999 1999
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 3b40a2f57ab..edad4bb218d 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL, c2 DATE NULL, c3 DATE NULL, UNIQUE(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -144,3 +145,4 @@ c1 c2 c3
2011 2011 2000
2011 2011 2011
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 84f626d3347..4d7cadac70c 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL, c2 DATE NULL, c3 DATE NULL, UNIQUE(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -147,3 +148,4 @@ c1 c2 c3
1999 2000 1999
2000 1999 1999
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 f34b39ec1b4..31f7db1dc9a 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL, c2 DATE NULL, c3 DATE NULL, UNIQUE(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -139,3 +140,4 @@ c1 c2 c3
1999 2000 1999
2000 1999 1999
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 f2cafdfce52..d7dfc9d794c 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
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NOT NULL, c3 DATE NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -144,3 +145,4 @@ c1 c2 c3
2011 2011 2000
2011 2011 2011
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
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 7185fc3c6ee..dbd6e2cf8a6 100644
--- a/mysql-test/suite/engines/funcs/r/up_calendar_range.result
+++ b/mysql-test/suite/engines/funcs/r/up_calendar_range.result
@@ -1,4 +1,5 @@
DROP TABLE IF EXISTS t1,t2,t3;
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL);
SET TIMESTAMP=1171346973;
INSERT INTO t1 (c1) VALUES(NOW());
@@ -104,3 +105,4 @@ c1
2007-02-13 09:09:33
2007-02-14 10:10:34
DROP TABLE t1;
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/de_calendar_range.test b/mysql-test/suite/engines/funcs/t/de_calendar_range.test
index c1e191fdd97..6e3f1915e9a 100644
--- a/mysql-test/suite/engines/funcs/t/de_calendar_range.test
+++ b/mysql-test/suite/engines/funcs/t/de_calendar_range.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1,t2,t3;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1) VALUES(NOW());
@@ -45,4 +47,5 @@ SELECT * FROM t1 ORDER BY c1;
DELETE FROM t1 WHERE c1 <= ADDTIME(NOW(),'2 02:01:01');
SELECT * FROM t1 ORDER BY c1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_calendar_2_unique_constraints_duplicate_update.test b/mysql-test/suite/engines/funcs/t/in_calendar_2_unique_constraints_duplicate_update.test
index 8c6f960b60d..5ae519abdc8 100644
--- a/mysql-test/suite/engines/funcs/t/in_calendar_2_unique_constraints_duplicate_update.test
+++ b/mysql-test/suite/engines/funcs/t/in_calendar_2_unique_constraints_duplicate_update.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NULL, c3 DATE NULL, PRIMARY KEY(c1), UNIQUE(c2));
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),ADDTIME(NOW(),'4 04:01:01'),NOW());
@@ -70,4 +72,6 @@ INSERT INTO t1 (c1,c2,c3) VALUES(2000,2000,2000) ON DUPLICATE KEY UPDATE c3=2011
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_duplicate_update.test b/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_duplicate_update.test
index 65c7c34f907..fdfb6edb139 100644
--- a/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_duplicate_update.test
+++ b/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_duplicate_update.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1) VALUES(NOW());
@@ -61,4 +63,5 @@ INSERT INTO t1 (c1) VALUES(1999) ON DUPLICATE KEY UPDATE c1=2011;
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_error.test b/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_error.test
index 36a8ef3a0a7..f65c705031b 100644
--- a/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_error.test
+++ b/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_error.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1) VALUES(NOW());
@@ -61,4 +63,5 @@ INSERT INTO t1 (c1) VALUES(2000);
INSERT INTO t1 (c1) VALUES(1999);
SELECT * FROM t1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_ignore.test b/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_ignore.test
index 36a8ef3a0a7..bac71b99a97 100644
--- a/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_ignore.test
+++ b/mysql-test/suite/engines/funcs/t/in_calendar_pk_constraint_ignore.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL PRIMARY KEY);
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1) VALUES(NOW());
@@ -61,4 +63,6 @@ INSERT INTO t1 (c1) VALUES(2000);
INSERT INTO t1 (c1) VALUES(1999);
SELECT * FROM t1;
DROP TABLE t1;
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_duplicate_update.test b/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_duplicate_update.test
index 20da85f5b66..e6235e77603 100644
--- a/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_duplicate_update.test
+++ b/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_duplicate_update.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL UNIQUE);
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1) VALUES(NOW());
@@ -61,4 +63,5 @@ INSERT INTO t1 (c1) VALUES(1999) ON DUPLICATE KEY UPDATE c1=2011;
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_error.test b/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_error.test
index 73b8c3d0775..f9d101d8327 100644
--- a/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_error.test
+++ b/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_error.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL UNIQUE);
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1) VALUES(NOW());
@@ -61,4 +63,5 @@ INSERT INTO t1 (c1) VALUES(2000);
INSERT INTO t1 (c1) VALUES(1999);
SELECT * FROM t1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_ignore.test b/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_ignore.test
index 91e4f8faef9..a4e96a7ccc3 100644
--- a/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_ignore.test
+++ b/mysql-test/suite/engines/funcs/t/in_calendar_unique_constraint_ignore.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL UNIQUE);
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1) VALUES(NOW());
@@ -53,4 +55,5 @@ INSERT INTO t1 (c1) VALUES(2000);
INSERT IGNORE INTO t1 (c1) VALUES(1999);
SELECT * FROM t1;
DROP TABLE t1;
-
+#restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_duplicate_update.test b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_duplicate_update.test
index a7648a55128..12307232d64 100644
--- a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_duplicate_update.test
+++ b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_duplicate_update.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NOT NULL, c3 DATE NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -85,4 +87,6 @@ INSERT INTO t1 (c1,c2,c3) VALUES(1999,1999,2000) ON DUPLICATE KEY UPDATE c1=2011
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_error.test b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_error.test
index 9678ddd716b..8d994cb3d7a 100644
--- a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_error.test
+++ b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_error.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NOT NULL, c3 DATE NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -93,4 +95,5 @@ INSERT INTO t1 (c1,c2,c3) VALUES(1999,1999,1999);
INSERT INTO t1 (c1,c2,c3) VALUES(1999,1999,2000);
SELECT * FROM t1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_ignore.test b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_ignore.test
index 9678ddd716b..8d994cb3d7a 100644
--- a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_ignore.test
+++ b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_pk_constraint_ignore.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NOT NULL, c3 DATE NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -93,4 +95,5 @@ INSERT INTO t1 (c1,c2,c3) VALUES(1999,1999,1999);
INSERT INTO t1 (c1,c2,c3) VALUES(1999,1999,2000);
SELECT * FROM t1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_duplicate_update.test b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_duplicate_update.test
index 13575722c1f..3d455bcb5d8 100644
--- a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_duplicate_update.test
+++ b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_duplicate_update.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL, c2 DATE NULL, c3 DATE NULL, UNIQUE(c1,c2,c3));
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -85,4 +87,5 @@ INSERT INTO t1 (c1,c2,c3) VALUES(1999,1999,2000) ON DUPLICATE KEY UPDATE c1=2011
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_error.test b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_error.test
index 916b0c527eb..9cbafd3b8d0 100644
--- a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_error.test
+++ b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_error.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL, c2 DATE NULL, c3 DATE NULL, UNIQUE(c1,c2,c3));
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -93,4 +95,5 @@ INSERT INTO t1 (c1,c2,c3) VALUES(1999,1999,1999);
INSERT INTO t1 (c1,c2,c3) VALUES(1999,1999,2000);
SELECT * FROM t1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_ignore.test b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_ignore.test
index b43ff52abe3..e313f29edfb 100644
--- a/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_ignore.test
+++ b/mysql-test/suite/engines/funcs/t/in_multicolumn_calendar_unique_constraint_ignore.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NULL, c2 DATE NULL, c3 DATE NULL, UNIQUE(c1,c2,c3));
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -85,4 +87,6 @@ INSERT IGNORE INTO t1 (c1,c2,c3) VALUES(1999,1999,2000);
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/in_multicolumn_number_pk_constraint_duplicate_update.test b/mysql-test/suite/engines/funcs/t/in_multicolumn_number_pk_constraint_duplicate_update.test
index 71848c1ac38..df4a194a2cf 100644
--- a/mysql-test/suite/engines/funcs/t/in_multicolumn_number_pk_constraint_duplicate_update.test
+++ b/mysql-test/suite/engines/funcs/t/in_multicolumn_number_pk_constraint_duplicate_update.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL, c2 DATE NOT NULL, c3 DATE NOT NULL, PRIMARY KEY(c1,c2,c3));
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1,c2,c3) VALUES(NOW(),NOW(),NOW());
@@ -93,4 +95,6 @@ INSERT INTO t1 (c1,c2,c3) VALUES(1999,1999,2000) ON DUPLICATE KEY UPDATE c1=2011
--sorted_result
SELECT * FROM t1;
DROP TABLE t1;
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/engines/funcs/t/up_calendar_range.test b/mysql-test/suite/engines/funcs/t/up_calendar_range.test
index 9c88d52f826..d4aca03199d 100644
--- a/mysql-test/suite/engines/funcs/t/up_calendar_range.test
+++ b/mysql-test/suite/engines/funcs/t/up_calendar_range.test
@@ -1,6 +1,8 @@
--disable_warnings
DROP TABLE IF EXISTS t1,t2,t3;
--enable_warnings
+# Set Correct timezone to match result
+SET TIME_ZONE="+03:00";
CREATE TABLE t1(c1 DATE NOT NULL);
SET TIMESTAMP=1171346973; # 2007-02-13 15:09:33
INSERT INTO t1 (c1) VALUES(NOW());
@@ -53,4 +55,5 @@ UPDATE t1 SET c1 = NOW() WHERE c1 >= ADDTIME(NOW(),'2 02:01:01');
--sorted_result
SELECT * FROM t1 ORDER BY c1;
DROP TABLE t1;
-
+# Restore timezone to default
+SET TIME_ZONE= @@global.time_zone;
diff --git a/mysql-test/suite/federated/combinations b/mysql-test/suite/federated/combinations
new file mode 100644
index 00000000000..18fd5f0d721
--- /dev/null
+++ b/mysql-test/suite/federated/combinations
@@ -0,0 +1,8 @@
+[old]
+--federated
+--plugin-load=$HA_FEDERATED_SO
+
+[X]
+--federated
+--plugin-load=$HA_FEDERATEDX_SO
+
diff --git a/mysql-test/suite/federated/federated.inc b/mysql-test/suite/federated/federated.inc
index ad640dcbb61..17410846604 100644
--- a/mysql-test/suite/federated/federated.inc
+++ b/mysql-test/suite/federated/federated.inc
@@ -1,5 +1,4 @@
--source include/not_embedded.inc
---source have_federated_db.inc
connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,);
connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,);
diff --git a/mysql-test/suite/federated/federated_partition.test b/mysql-test/suite/federated/federated_partition.test
index 6f093bfb63d..13f26ecd756 100644
--- a/mysql-test/suite/federated/federated_partition.test
+++ b/mysql-test/suite/federated/federated_partition.test
@@ -1,6 +1,7 @@
#
# Tests for partitioned FEDERATED
#
+source have_federatedx.inc;
source include/have_partition.inc;
source include/have_innodb.inc;
source federated.inc;
diff --git a/mysql-test/suite/federated/federated_server.result b/mysql-test/suite/federated/federated_server.result
index ad9dfd7ee38..e2a5d60302b 100644
--- a/mysql-test/suite/federated/federated_server.result
+++ b/mysql-test/suite/federated/federated_server.result
@@ -213,7 +213,7 @@ id name
alter server s1 options (database 'db_bogus');
flush tables;
select * from federated.t1;
-ERROR 42000: Received error: 1044 : Access denied for user 'test_fed'@'localhost' to database 'db_bogus'
+Got one of the listed errors
drop server if exists 's1';
ERROR 42000: Access denied; you need (at least one of) the SUPER privilege(s) for this operation
create server 's1' foreign data wrapper 'mysql' options
diff --git a/mysql-test/suite/federated/federated_server.test b/mysql-test/suite/federated/federated_server.test
index 315aaa807a7..9f7f833a401 100644
--- a/mysql-test/suite/federated/federated_server.test
+++ b/mysql-test/suite/federated/federated_server.test
@@ -239,7 +239,7 @@ alter server s1 options (database 'db_bogus');
connection master;
flush tables;
---error ER_DBACCESS_DENIED_ERROR
+--error ER_DBACCESS_DENIED_ERROR,ER_CONNECT_TO_FOREIGN_DATA_SOURCE
select * from federated.t1;
connection conn_select;
diff --git a/mysql-test/suite/federated/federated_transactions.test b/mysql-test/suite/federated/federated_transactions.test
index cd08d310273..637df45a52a 100644
--- a/mysql-test/suite/federated/federated_transactions.test
+++ b/mysql-test/suite/federated/federated_transactions.test
@@ -1,3 +1,4 @@
+source have_federatedx.inc;
source include/have_innodb.inc;
source federated.inc;
diff --git a/mysql-test/suite/federated/federated.result b/mysql-test/suite/federated/federatedx.result
index 2ece1a32b4f..2ece1a32b4f 100644
--- a/mysql-test/suite/federated/federated.result
+++ b/mysql-test/suite/federated/federatedx.result
diff --git a/mysql-test/suite/federated/federated.test b/mysql-test/suite/federated/federatedx.test
index 7789070adc3..cabcf0cea1b 100644
--- a/mysql-test/suite/federated/federated.test
+++ b/mysql-test/suite/federated/federatedx.test
@@ -7,6 +7,7 @@
# should work with embedded server after mysqltest is fixed
--source include/not_embedded.inc
--source federated.inc
+--source have_federatedx.inc
connection default;
diff --git a/mysql-test/suite/federated/have_federated_db.inc b/mysql-test/suite/federated/have_federated_db.inc
deleted file mode 100644
index 81f49aaa48e..00000000000
--- a/mysql-test/suite/federated/have_federated_db.inc
+++ /dev/null
@@ -1,6 +0,0 @@
-if (!`SELECT count(*) FROM information_schema.engines WHERE
- (support = 'YES' OR support = 'DEFAULT') AND
- engine = 'federated'`)
-{
- skip Need federated engine;
-}
diff --git a/mysql-test/suite/federated/have_federatedx.inc b/mysql-test/suite/federated/have_federatedx.inc
new file mode 100644
index 00000000000..56ce31f5b2f
--- /dev/null
+++ b/mysql-test/suite/federated/have_federatedx.inc
@@ -0,0 +1,5 @@
+if (!`SELECT count(*) FROM information_schema.plugins WHERE
+ plugin_name = 'federated' AND plugin_status = 'active' AND
+ plugin_description LIKE '%FederatedX%'`){
+ skip Need FederatedX engine;
+}
diff --git a/mysql-test/suite/federated/suite.opt b/mysql-test/suite/federated/have_federatedx.opt
index 2cce1887441..22f40b6d3d7 100644
--- a/mysql-test/suite/federated/suite.opt
+++ b/mysql-test/suite/federated/have_federatedx.opt
@@ -1,2 +1 @@
---federated
--plugin-load=$HA_FEDERATEDX_SO
diff --git a/mysql-test/suite/federated/suite.pm b/mysql-test/suite/federated/suite.pm
new file mode 100644
index 00000000000..06458b97adc
--- /dev/null
+++ b/mysql-test/suite/federated/suite.pm
@@ -0,0 +1,20 @@
+package My::Suite::Federated;
+
+@ISA = qw(My::Suite);
+
+############# initialization ######################
+my @combinations;
+
+push @combinations, 'old'
+ if $ENV{HA_FEDERATED_SO} and not $::mysqld_variables{'federated'};
+push @combinations, 'X'
+ if $ENV{HA_FEDERATEDX_SO} or $::mysqld_variables{'federated'};
+
+return "Neither Federated nor FederatedX are available" unless @combinations;
+
+$ENV{FEDERATED_COMBINATIONS}=join ':', @combinations
+ unless $ENV{FEDERATED_COMBINATIONS};
+
+############# return an object ######################
+bless { };
+
diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result
index e2bcd1f5047..d9cd0f1e7f8 100644
--- a/mysql-test/suite/funcs_1/r/innodb_views.result
+++ b/mysql-test/suite/funcs_1/r/innodb_views.result
@@ -21082,6 +21082,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
@@ -21112,6 +21114,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/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result
index c93febe8cdf..864cbb93b29 100644
--- a/mysql-test/suite/funcs_1/r/memory_views.result
+++ b/mysql-test/suite/funcs_1/r/memory_views.result
@@ -21084,6 +21084,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
@@ -21114,6 +21116,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_views-big.result b/mysql-test/suite/funcs_1/r/myisam_views-big.result
index b4c04c80a13..f4025dfef2a 100644
--- a/mysql-test/suite/funcs_1/r/myisam_views-big.result
+++ b/mysql-test/suite/funcs_1/r/myisam_views-big.result
@@ -22751,6 +22751,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
@@ -22781,6 +22783,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/t/is_engines_federated.test b/mysql-test/suite/funcs_1/t/is_engines_federated.test
index 81eac89c0d2..f39edefe43c 100644
--- a/mysql-test/suite/funcs_1/t/is_engines_federated.test
+++ b/mysql-test/suite/funcs_1/t/is_engines_federated.test
@@ -9,7 +9,7 @@
#
let $engine_type= FEDERATED;
---source suite/federated/have_federated_db.inc
+--source suite/federated/have_federatedx.inc
--vertical_results
eval SELECT * FROM information_schema.engines
WHERE ENGINE = '$engine_type';
diff --git a/mysql-test/suite/funcs_1/views/views_master.inc b/mysql-test/suite/funcs_1/views/views_master.inc
index 47d4fcfb571..bcb0662e9a4 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 ;
diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result
index a33099661aa..785270be600 100644
--- a/mysql-test/suite/innodb/r/innodb-index.result
+++ b/mysql-test/suite/innodb/r/innodb-index.result
@@ -1045,6 +1045,20 @@ COMMIT;
UPDATE bug12547647 SET c = REPEAT('b',16928);
ERROR HY000: Undo log record is too big.
DROP TABLE bug12547647;
+SET @r=REPEAT('a',500);
+CREATE TABLE t1(a INT,
+v1 VARCHAR(500), v2 VARCHAR(500), v3 VARCHAR(500),
+v4 VARCHAR(500), v5 VARCHAR(500), v6 VARCHAR(500),
+v7 VARCHAR(500), v8 VARCHAR(500), v9 VARCHAR(500),
+v10 VARCHAR(500), v11 VARCHAR(500), v12 VARCHAR(500),
+v13 VARCHAR(500), v14 VARCHAR(500), v15 VARCHAR(500),
+v16 VARCHAR(500), v17 VARCHAR(500), v18 VARCHAR(500)
+) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+CREATE INDEX idx1 ON t1(a,v1);
+INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
+UPDATE t1 SET a=1000;
+DELETE FROM t1;
+DROP TABLE t1;
set global innodb_file_per_table=0;
set global innodb_file_format=Antelope;
set global innodb_file_format_max=Antelope;
diff --git a/mysql-test/suite/innodb/r/innodb-lock.result b/mysql-test/suite/innodb/r/innodb-lock.result
index 41f308788a2..439a8d6513c 100644
--- a/mysql-test/suite/innodb/r/innodb-lock.result
+++ b/mysql-test/suite/innodb/r/innodb-lock.result
@@ -89,3 +89,20 @@ commit;
# Connection 'con1'.
commit;
drop table t1;
+#
+#Bug#12842206 INNODB LOCKING REGRESSION FOR INSERT IGNORE
+#fixed by re-fixing Bug#7975
+#aka Bug#11759688 52020: InnoDB can still deadlock on just INSERT...
+#
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(3,1);
+BEGIN;
+INSERT IGNORE INTO t1 VALUES(3,14);
+BEGIN;
+INSERT IGNORE INTO t1 VALUES(3,23);
+SELECT * FROM t1 FOR UPDATE;
+COMMIT;
+a b
+3 1
+COMMIT;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index efb47f65e6d..ff9f7057622 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -1302,6 +1302,20 @@ ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fail
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 (
+c1 VARCHAR(8), c2 VARCHAR(8),
+PRIMARY KEY (c1, c2)
+) ENGINE=InnoDB;
+CREATE TABLE t2 (
+c0 INT PRIMARY KEY,
+c1 VARCHAR(8) UNIQUE,
+FOREIGN KEY (c1) REFERENCES t1 (c1) ON UPDATE CASCADE
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('old', 'somevalu'), ('other', 'anyvalue');
+INSERT INTO t2 VALUES (10, 'old'), (20, 'other');
+UPDATE t1 SET c1 = 'other' WHERE c1 = 'old';
+ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 2 would lead to a duplicate entry
+DROP TABLE t2,t1;
create table t1(
id int primary key,
pid int,
@@ -1576,6 +1590,12 @@ 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
@@ -1674,7 +1694,7 @@ 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
-1066
+1071
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
866
@@ -1693,74 +1713,7 @@ variable_value - @innodb_row_lock_time_max_orig
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;
-show variables like "innodb_thread_concurrency";
-Variable_name Value
-innodb_thread_concurrency 0
-set global innodb_thread_concurrency=1001;
-Warnings:
-Warning 1292 Truncated incorrect innodb_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
-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 innodb_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;
-set session old_alter_table=1;
drop table if exists t1,t2,t3;
--- Testing varchar ---
--- Testing varchar ---
@@ -2334,7 +2287,6 @@ select * from t1 where a=20 and b is null;
a b
20 NULL
drop table t1;
-set session old_alter_table=0;
create table t1 (v varchar(65530), key(v));
Warnings:
Warning 1071 Specified key was too long; max key length is 767 bytes
diff --git a/mysql-test/suite/innodb/r/innodb_bug12661768.result b/mysql-test/suite/innodb/r/innodb_bug12661768.result
new file mode 100644
index 00000000000..1f2401ddd47
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_bug12661768.result
@@ -0,0 +1,2 @@
+SET SESSION foreign_key_checks=0;
+ERROR 23000: Upholding foreign key constraints for table 'bug12661768_1', entry '3-bbb', key 2 would lead to a duplicate entry
diff --git a/mysql-test/suite/innodb/r/innodb_bug59641.result b/mysql-test/suite/innodb/r/innodb_bug59641.result
index c94c2105e98..5062c69558b 100644
--- a/mysql-test/suite/innodb/r/innodb_bug59641.result
+++ b/mysql-test/suite/innodb/r/innodb_bug59641.result
@@ -1,5 +1,5 @@
call mtr.add_suppression("Found 3 prepared XA transactions");
-FLUSH TABLES;
+flush tables;
CREATE TABLE t(a INT PRIMARY KEY, b INT)ENGINE=InnoDB;
INSERT INTO t VALUES(2,2),(4,4),(8,8),(16,16),(32,32);
COMMIT;
diff --git a/mysql-test/suite/innodb/r/innodb_gis.result b/mysql-test/suite/innodb/r/innodb_gis.result
index d401093cabc..36b37e4ccd8 100644
--- a/mysql-test/suite/innodb/r/innodb_gis.result
+++ b/mysql-test/suite/innodb/r/innodb_gis.result
@@ -572,7 +572,7 @@ COUNT(*)
EXPLAIN
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t2 ref p p 28 const 2 Using where
+1 SIMPLE t2 ref p p 28 const # Using where
SELECT COUNT(*) FROM t2 WHERE p=POINTFROMTEXT('POINT(1 2)');
COUNT(*)
2
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..30e58aacff5 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;
@@ -119,7 +121,7 @@ key PRIMARY
key_len 4
ref t2.a
rows 1
-Extra Using where
+Extra Using index condition; Using where
id 2
select_type DERIVED
table NULL
@@ -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;
@@ -323,7 +328,7 @@ key PRIMARY
key_len 4
ref t2.a
rows 1
-Extra Using where
+Extra Using index condition; Using where
id 2
select_type DERIVED
table NULL
@@ -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 813288fe601..5223c566475 100644
--- a/mysql-test/suite/innodb/r/innodb_mysql.result
+++ b/mysql-test/suite/innodb/r/innodb_mysql.result
@@ -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
@@ -1430,9 +1430,9 @@ DROP TABLE t1;
create table t1 (a bit(1) not null,b int) engine=myisam;
create table t2 (c int) engine=innodb;
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch='partial_match_rowid_merge=off,partial_match_table_scan=off';
+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
@@ -2685,11 +2685,54 @@ rows 3
Extra Using index
DROP TABLE t1;
#
+# Bug#56862 Execution of a query that uses index merge returns a wrong result
+#
+CREATE TABLE t1 (
+pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+a int,
+b int,
+INDEX idx(a))
+ENGINE=INNODB;
+INSERT INTO t1(a,b) VALUES
+(11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500),
+(3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800),
+(6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700),
+(13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000);
+INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1;
+INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1;
+INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1 VALUES (1000000, 0, 0);
+SET SESSION sort_buffer_size = 1024*36;
+EXPLAIN
+SELECT COUNT(*) FROM
+(SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
+WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 index_merge PRIMARY,idx idx,PRIMARY 5,4 NULL 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;
+COUNT(*)
+1537
+SET SESSION sort_buffer_size = DEFAULT;
+DROP TABLE t1;
+#
# ALTER TABLE IGNORE didn't ignore duplicates for unique add index
#
create table t1 (a int primary key, b int) engine = innodb;
insert into t1 values (1,1),(2,1);
alter ignore table t1 add unique `main` (b);
+select * from t1;
+a b
+1 1
drop table t1;
End of 5.1 tests
#
@@ -2737,8 +2780,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 <derived2> ALL NULL NULL NULL NULL 1536
-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/r/innodb_replace.result b/mysql-test/suite/innodb/r/innodb_replace.result
new file mode 100644
index 00000000000..30009b8ddc9
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb_replace.result
@@ -0,0 +1,77 @@
+#
+#Bug#11759688 52020: InnoDB can still deadlock
+#on just INSERT...ON DUPLICATE KEY
+#a.k.a. Bug#7975 deadlock without any locking, simple select and update
+#
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;
+INSERT INTO t1 VALUES(3,1);
+BEGIN;
+SET DEBUG_SYNC='write_row_noreplace SIGNAL insert1 WAIT_FOR select1';
+INSERT INTO t1 VALUES(3,2);
+SET DEBUG_SYNC='now WAIT_FOR insert1';
+SELECT * FROM t1 LOCK IN SHARE MODE;
+a b
+3 1
+SELECT * FROM t1 FOR UPDATE;
+SET DEBUG_SYNC='now SIGNAL select1';
+ERROR 23000: Duplicate entry '3' for key 'PRIMARY'
+INSERT INTO t1 VALUES(3,3) ON DUPLICATE KEY UPDATE b=b+10;
+ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
+COMMIT;
+SET DEBUG_SYNC='write_row_replace SIGNAL insert2 WAIT_FOR select2';
+REPLACE INTO t1 VALUES(3,4);
+SET DEBUG_SYNC='now WAIT_FOR insert2';
+SELECT * FROM t1;
+a b
+3 11
+SELECT * FROM t1 LOCK IN SHARE MODE;
+SET DEBUG_SYNC='now SIGNAL select2';
+SET DEBUG_SYNC='write_row_replace SIGNAL insert3 WAIT_FOR select3';
+INSERT INTO t1 VALUES(3,5) ON DUPLICATE KEY UPDATE b=b+20;
+a b
+3 4
+SET DEBUG_SYNC='now WAIT_FOR insert3';
+SELECT b FROM t1 LOCK IN SHARE MODE;
+SET DEBUG_SYNC='now SIGNAL select3';
+b
+24
+SET DEBUG_SYNC='write_row_noreplace SIGNAL insert4 WAIT_FOR select4';
+LOAD DATA INFILE '../../std_data/loaddata5.dat' INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (a, b);
+SET DEBUG_SYNC='now WAIT_FOR insert4';
+SELECT b FROM t1 WHERE a=3 LOCK IN SHARE MODE;
+b
+24
+SELECT b FROM t1 WHERE a=3 FOR UPDATE;
+SET DEBUG_SYNC='now SIGNAL select4';
+b
+24
+ERROR 23000: Duplicate entry '3' for key 'PRIMARY'
+SET DEBUG_SYNC='write_row_noreplace SIGNAL insert5 WAIT_FOR select5';
+LOAD DATA INFILE '../../std_data/loaddata5.dat' IGNORE INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (a, b);
+SET DEBUG_SYNC='now WAIT_FOR insert5';
+SELECT * FROM t1;
+a b
+3 24
+SELECT * FROM t1 WHERE a=3 LOCK IN SHARE MODE;
+a b
+3 24
+SELECT * FROM t1 WHERE a=3 FOR UPDATE;
+SET DEBUG_SYNC='now SIGNAL select5';
+a b
+3 24
+SET DEBUG_SYNC='write_row_replace SIGNAL insert6 WAIT_FOR select6';
+LOAD DATA INFILE '../../std_data/loaddata5.dat' REPLACE INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (a, b);
+SET DEBUG_SYNC='now WAIT_FOR insert6';
+SELECT * FROM t1;
+a b
+1 2
+3 24
+5 6
+SELECT a,b FROM t1 LOCK IN SHARE MODE;
+SET DEBUG_SYNC='now SIGNAL select6';
+a b
+1 2
+3 4
+5 6
+SET DEBUG_SYNC='RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-index.test b/mysql-test/suite/innodb/t/innodb-index.test
index 2402c74fe53..beeda98c7f1 100644
--- a/mysql-test/suite/innodb/t/innodb-index.test
+++ b/mysql-test/suite/innodb/t/innodb-index.test
@@ -530,6 +530,24 @@ COMMIT;
--error ER_UNDO_RECORD_TOO_BIG
UPDATE bug12547647 SET c = REPEAT('b',16928);
DROP TABLE bug12547647;
+# Bug#12637786
+SET @r=REPEAT('a',500);
+CREATE TABLE t1(a INT,
+ v1 VARCHAR(500), v2 VARCHAR(500), v3 VARCHAR(500),
+ v4 VARCHAR(500), v5 VARCHAR(500), v6 VARCHAR(500),
+ v7 VARCHAR(500), v8 VARCHAR(500), v9 VARCHAR(500),
+ v10 VARCHAR(500), v11 VARCHAR(500), v12 VARCHAR(500),
+ v13 VARCHAR(500), v14 VARCHAR(500), v15 VARCHAR(500),
+ v16 VARCHAR(500), v17 VARCHAR(500), v18 VARCHAR(500)
+) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+
+CREATE INDEX idx1 ON t1(a,v1);
+INSERT INTO t1 VALUES(9,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r,@r);
+UPDATE t1 SET a=1000;
+DELETE FROM t1;
+# Let the purge thread clean up this file.
+-- sleep 10
+DROP TABLE t1;
eval set global innodb_file_per_table=$per_table;
eval set global innodb_file_format=$format;
diff --git a/mysql-test/suite/innodb/t/innodb-lock.test b/mysql-test/suite/innodb/t/innodb-lock.test
index 05501ec0d03..49fe1127074 100644
--- a/mysql-test/suite/innodb/t/innodb-lock.test
+++ b/mysql-test/suite/innodb/t/innodb-lock.test
@@ -126,3 +126,44 @@ commit;
drop table t1;
# End of 4.1 tests
+
+--echo #
+--echo #Bug#12842206 INNODB LOCKING REGRESSION FOR INSERT IGNORE
+--echo #fixed by re-fixing Bug#7975
+--echo #aka Bug#11759688 52020: InnoDB can still deadlock on just INSERT...
+--echo #
+
+connection default;
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES(3,1);
+
+BEGIN;
+# this used to wrongly acquire an X lock; now it takes an S lock
+INSERT IGNORE INTO t1 VALUES(3,14);
+
+connection con1;
+BEGIN;
+# this used to wrongly acquire an X lock; now it takes an S lock
+INSERT IGNORE INTO t1 VALUES(3,23);
+--send
+SELECT * FROM t1 FOR UPDATE;
+
+connection con2;
+# Check that the above SELECT is blocked
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = 'Sending data' and
+ info = 'SELECT * FROM t1 FOR UPDATE';
+--source include/wait_condition.inc
+
+connection default;
+COMMIT;
+connection con1;
+reap;
+COMMIT;
+disconnect con1;
+disconnect con2;
+
+connection default;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index 44cd2bd9573..6150f4252cd 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -1041,14 +1041,32 @@ create table `t2` (`id` int( 11 ) not null default '0',unique key `id` ( `id` )
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 ) ;
---error 1451
+--error ER_ROW_IS_REFERENCED_2
delete t3,t2,t1 from t1,t2,t3 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
---error 1451
+--error ER_ROW_IS_REFERENCED_2
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 1054
+--error ER_BAD_FIELD_ERROR
update t3 set t3.id=7 where t1.id =1 and t2.id = t1.id and t3.id = t2.id;
drop table t3,t2,t1;
+# test ON UPDATE CASCADE
+CREATE TABLE t1 (
+ c1 VARCHAR(8), c2 VARCHAR(8),
+ PRIMARY KEY (c1, c2)
+) ENGINE=InnoDB;
+
+CREATE TABLE t2 (
+ c0 INT PRIMARY KEY,
+ c1 VARCHAR(8) UNIQUE,
+ FOREIGN KEY (c1) REFERENCES t1 (c1) ON UPDATE CASCADE
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES ('old', 'somevalu'), ('other', 'anyvalue');
+INSERT INTO t2 VALUES (10, 'old'), (20, 'other');
+-- error ER_FOREIGN_DUPLICATE_KEY
+UPDATE t1 SET c1 = 'other' WHERE c1 = 'old';
+DROP TABLE t2,t1;
+
#
# test for recursion depth limit
#
@@ -1228,11 +1246,11 @@ drop table t1;
#
# Bug #4082: integer truncation
#
-# disable because the bug has resurfaced
-#create table t1(a int(1) , b int(1)) engine=innodb;
-#insert into t1 values ('1111', '3333');
-#select distinct concat(a, b) from t1;
-#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;
+drop table t1;
#
# BUG#7709 test case - Boolean fulltext query against unsupported
@@ -1334,43 +1352,6 @@ SELECT variable_value - @innodb_row_lock_time_orig FROM information_schema.globa
SELECT variable_value - @innodb_row_lock_time_max_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_max';
SELECT variable_value - @innodb_row_lock_time_avg_orig FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg';
-# Test for innodb_sync_spin_loops variable
-SET @innodb_sync_spin_loops_orig = @@innodb_sync_spin_loops;
-show variables like "innodb_sync_spin_loops";
-set global innodb_sync_spin_loops=1000;
-show variables like "innodb_sync_spin_loops";
-set global innodb_sync_spin_loops=0;
-show variables like "innodb_sync_spin_loops";
-set global innodb_sync_spin_loops=20;
-show variables like "innodb_sync_spin_loops";
-set global innodb_sync_spin_loops=@innodb_sync_spin_loops_orig;
-
-# Test for innodb_thread_concurrency variable
-show variables like "innodb_thread_concurrency";
-set global innodb_thread_concurrency=1001;
-show variables like "innodb_thread_concurrency";
-set global innodb_thread_concurrency=0;
-show variables like "innodb_thread_concurrency";
-set global innodb_thread_concurrency=16;
-show variables like "innodb_thread_concurrency";
-
-# Test for innodb_concurrency_tickets variable
-show variables like "innodb_concurrency_tickets";
-set global innodb_concurrency_tickets=1000;
-show variables like "innodb_concurrency_tickets";
-set global innodb_concurrency_tickets=0;
-show variables like "innodb_concurrency_tickets";
-set global innodb_concurrency_tickets=500;
-show variables like "innodb_concurrency_tickets";
-
-# Test for innodb_thread_sleep_delay variable
-show variables like "innodb_thread_sleep_delay";
-set global innodb_thread_sleep_delay=100000;
-show variables like "innodb_thread_sleep_delay";
-set global innodb_thread_sleep_delay=0;
-show variables like "innodb_thread_sleep_delay";
-set global innodb_thread_sleep_delay=10000;
-show variables like "innodb_thread_sleep_delay";
#
# Test varchar
@@ -1378,10 +1359,7 @@ show variables like "innodb_thread_sleep_delay";
let $default=`select @@storage_engine`;
set storage_engine=INNODB;
-# this should be fixed by MySQL (see Bug #51451)
-set session old_alter_table=1;
source include/varchar.inc;
-set session old_alter_table=0;
#
# Some errors/warnings on create
diff --git a/mysql-test/suite/innodb/t/innodb_bug12661768.test b/mysql-test/suite/innodb/t/innodb_bug12661768.test
new file mode 100644
index 00000000000..01549a7e9e9
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_bug12661768.test
@@ -0,0 +1,50 @@
+#
+# Bug#12661768 UPDATE IGNORE CRASHES SERVER IF TABLE IS INNODB AND IT IS
+# PARENT FOR OTHER ONE
+#
+
+-- source include/have_innodb.inc
+
+SET SESSION foreign_key_checks=0;
+
+# only interested that the "UPDATE IGNORE" at the end does not crash the server
+
+-- disable_query_log
+-- disable_result_log
+
+SET NAMES utf8;
+
+-- let $t1_name = bug12661768_1
+-- let $t2_name = bug12661768_2
+-- let $fk_name = ab_on_2
+-- let $key_str = 'bbb'
+
+eval DROP TABLE IF EXISTS `$t2_name`, `$t1_name`;
+
+eval CREATE TABLE `$t1_name` (
+ a INT,
+ b VARCHAR(512),
+ PRIMARY KEY (a, b)
+) ENGINE=INNODB;
+
+eval CREATE TABLE `$t2_name` (
+ id INT,
+ a INT,
+ b VARCHAR(512),
+ PRIMARY KEY (id),
+ UNIQUE KEY `$fk_name` (a, b),
+ FOREIGN KEY (a, b) REFERENCES `$t1_name` (a, b)
+ ON DELETE CASCADE ON UPDATE CASCADE
+) ENGINE=INNODB;
+
+eval INSERT INTO `$t1_name` VALUES (1, $key_str);
+eval INSERT INTO `$t2_name` VALUES (100, 1, $key_str), (101, 3, $key_str);
+
+SET SESSION foreign_key_checks=1;
+
+-- enable_result_log
+
+-- error ER_FOREIGN_DUPLICATE_KEY
+eval UPDATE IGNORE `$t1_name` SET a = 3;
+
+eval DROP TABLE `$t2_name`, `$t1_name`;
diff --git a/mysql-test/suite/innodb/t/innodb_bug59641.test b/mysql-test/suite/innodb/t/innodb_bug59641.test
index bf9845b8e6f..94b9ed8f9ed 100644
--- a/mysql-test/suite/innodb/t/innodb_bug59641.test
+++ b/mysql-test/suite/innodb/t/innodb_bug59641.test
@@ -3,7 +3,9 @@
-- source include/not_embedded.inc
# The server would issue this warning on restart.
call mtr.add_suppression("Found 3 prepared XA transactions");
-FLUSH TABLES;
+
+# Close tables used by other tests (to not get crashed myisam tables)
+flush tables;
CREATE TABLE t(a INT PRIMARY KEY, b INT)ENGINE=InnoDB;
INSERT INTO t VALUES(2,2),(4,4),(8,8),(16,16),(32,32);
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 5a0aaa86d4c..ef448680f93 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
@@ -139,10 +139,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
---replace_result "Using index condition; Using where" "Using where"
+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,10 +238,12 @@ begin;
--echo #
--echo # Verify that JT_EQ_REF is used.
--vertical_results
---replace_result "Using index condition; Using where" "Using where"
+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 4cdcf2ce5cd..498bd3f443f 100644
--- a/mysql-test/suite/innodb/t/innodb_mysql.test
+++ b/mysql-test/suite/innodb/t/innodb_mysql.test
@@ -861,12 +861,57 @@ CREATE INDEX b ON t1(a,b,c,d);
DROP TABLE t1;
--echo #
+--echo # Bug#56862 Execution of a query that uses index merge returns a wrong result
+--echo #
+
+CREATE TABLE t1 (
+ pk int NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ a int,
+ b int,
+ INDEX idx(a))
+ENGINE=INNODB;
+
+INSERT INTO t1(a,b) VALUES
+ (11, 1100), (2, 200), (1, 100), (14, 1400), (5, 500),
+ (3, 300), (17, 1700), (4, 400), (12, 1200), (8, 800),
+ (6, 600), (18, 1800), (9, 900), (10, 1000), (7, 700),
+ (13, 1300), (15, 1500), (19, 1900), (16, 1600), (20, 2000);
+INSERT INTO t1(a,b) SELECT a+20, b+2000 FROM t1;
+INSERT INTO t1(a,b) SELECT a+40, b+4000 FROM t1;
+INSERT INTO t1(a,b) SELECT a+80, b+8000 FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1(a,b) SELECT a,b FROM t1;
+INSERT INTO t1 VALUES (1000000, 0, 0);
+
+SET SESSION sort_buffer_size = 1024*36;
+
+EXPLAIN
+SELECT COUNT(*) FROM
+ (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
+ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+
+SELECT COUNT(*) FROM
+ (SELECT * FROM t1 FORCE INDEX (idx,PRIMARY)
+ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
+
+SET SESSION sort_buffer_size = DEFAULT;
+
+DROP TABLE t1;
+
+--echo #
--echo # ALTER TABLE IGNORE didn't ignore duplicates for unique add index
--echo #
create table t1 (a int primary key, b int) engine = innodb;
insert into t1 values (1,1),(2,1);
alter ignore table t1 add unique `main` (b);
+select * from t1;
drop table t1;
--echo End of 5.1 tests
diff --git a/mysql-test/suite/innodb/t/innodb_replace.test b/mysql-test/suite/innodb/t/innodb_replace.test
new file mode 100644
index 00000000000..a35f423c85e
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb_replace.test
@@ -0,0 +1,186 @@
+--source include/have_innodb.inc
+--source include/have_debug_sync.inc
+
+--echo #
+--echo #Bug#11759688 52020: InnoDB can still deadlock
+--echo #on just INSERT...ON DUPLICATE KEY
+--echo #a.k.a. Bug#7975 deadlock without any locking, simple select and update
+--echo #
+
+CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES(3,1);
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+connection con1;
+
+BEGIN;
+# normal INSERT of a duplicate should only S-lock the existing record (3,1)
+SET DEBUG_SYNC='write_row_noreplace SIGNAL insert1 WAIT_FOR select1';
+--send
+INSERT INTO t1 VALUES(3,2);
+
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR insert1';
+# this should S-lock (3,1); no conflict
+SELECT * FROM t1 LOCK IN SHARE MODE;
+# this should X-lock (3,1), conflicting with con1
+--send
+SELECT * FROM t1 FOR UPDATE;
+
+connection con2;
+# Check that the above SELECT is blocked
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = 'Sending data' and
+ info = 'SELECT * FROM t1 FOR UPDATE';
+--source include/wait_condition.inc
+SET DEBUG_SYNC='now SIGNAL select1';
+
+connection con1;
+--error ER_DUP_ENTRY
+reap;
+# We are still holding an S-lock on (3,1) after the failed INSERT.
+# The following will upgrade it to an X-lock, causing a deadlock.
+# InnoDB should resolve the deadlock by aborting the blocked SELECT.
+INSERT INTO t1 VALUES(3,3) ON DUPLICATE KEY UPDATE b=b+10;
+
+connection default;
+--error ER_LOCK_DEADLOCK
+reap;
+connection con1;
+COMMIT;
+
+SET DEBUG_SYNC='write_row_replace SIGNAL insert2 WAIT_FOR select2';
+--send
+REPLACE INTO t1 VALUES(3,4);
+
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR insert2';
+SELECT * FROM t1;
+--send
+SELECT * FROM t1 LOCK IN SHARE MODE;
+
+connection con2;
+# Check that the above SELECT is blocked because of X lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = 'Sending data' and
+ info = 'SELECT * FROM t1 LOCK IN SHARE MODE';
+--source include/wait_condition.inc
+SET DEBUG_SYNC='now SIGNAL select2';
+
+connection con1;
+reap;
+
+SET DEBUG_SYNC='write_row_replace SIGNAL insert3 WAIT_FOR select3';
+--send
+INSERT INTO t1 VALUES(3,5) ON DUPLICATE KEY UPDATE b=b+20;
+
+connection default;
+reap;
+SET DEBUG_SYNC='now WAIT_FOR insert3';
+--send
+SELECT b FROM t1 LOCK IN SHARE MODE;
+
+connection con2;
+# Check that the above SELECT is blocked because of X lock.
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = 'Sending data' and
+ info = 'SELECT b FROM t1 LOCK IN SHARE MODE';
+--source include/wait_condition.inc
+SET DEBUG_SYNC='now SIGNAL select3';
+
+connection default;
+reap;
+
+connection con1;
+reap;
+SET DEBUG_SYNC='write_row_noreplace SIGNAL insert4 WAIT_FOR select4';
+--send
+LOAD DATA INFILE '../../std_data/loaddata5.dat' INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (a, b);
+
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR insert4';
+# this should S-lock (3,1); no conflict
+SELECT b FROM t1 WHERE a=3 LOCK IN SHARE MODE;
+# this should X-lock (3,1), conflicting with con1
+--send
+SELECT b FROM t1 WHERE a=3 FOR UPDATE;
+
+connection con2;
+# Check that the above SELECT is blocked
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = 'statistics' and
+ info = 'SELECT b FROM t1 WHERE a=3 FOR UPDATE';
+--source include/wait_condition.inc
+SET DEBUG_SYNC='now SIGNAL select4';
+
+connection default;
+reap;
+
+connection con1;
+--error ER_DUP_ENTRY
+reap;
+SET DEBUG_SYNC='write_row_noreplace SIGNAL insert5 WAIT_FOR select5';
+--send
+LOAD DATA INFILE '../../std_data/loaddata5.dat' IGNORE INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (a, b);
+
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR insert5';
+SELECT * FROM t1;
+# this should S-lock; no conflict
+SELECT * FROM t1 WHERE a=3 LOCK IN SHARE MODE;
+# this should X-lock, conflicting with the S-lock of the IGNORE in con1
+--send
+SELECT * FROM t1 WHERE a=3 FOR UPDATE;
+
+connection con2;
+# Check that the above SELECT is blocked
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = 'statistics' and
+ info = 'SELECT * FROM t1 WHERE a=3 FOR UPDATE';
+--source include/wait_condition.inc
+SET DEBUG_SYNC='now SIGNAL select5';
+
+connection con1;
+reap;
+connection default;
+reap;
+
+connection con1;
+SET DEBUG_SYNC='write_row_replace SIGNAL insert6 WAIT_FOR select6';
+--send
+LOAD DATA INFILE '../../std_data/loaddata5.dat' REPLACE INTO TABLE t1 FIELDS TERMINATED BY '' ENCLOSED BY '' (a, b);
+
+connection default;
+SET DEBUG_SYNC='now WAIT_FOR insert6';
+SELECT * FROM t1;
+# this should conflict with the X-lock acquired by the REPLACE
+--send
+SELECT a,b FROM t1 LOCK IN SHARE MODE;
+
+connection con2;
+# Check that the above SELECT is blocked
+let $wait_condition=
+ select count(*) = 1 from information_schema.processlist
+ where state = 'Sending data' and
+ info = 'SELECT a,b FROM t1 LOCK IN SHARE MODE';
+--source include/wait_condition.inc
+SET DEBUG_SYNC='now SIGNAL select6';
+
+connection con1;
+reap;
+connection default;
+reap;
+
+disconnect con1;
+disconnect con2;
+
+connection default;
+SET DEBUG_SYNC='RESET';
+DROP TABLE t1;
diff --git a/mysql-test/suite/maria/r/maria-autozerofill.result b/mysql-test/suite/maria/r/maria-autozerofill.result
index ad0ea32362a..81df4cbab90 100644
--- a/mysql-test/suite/maria/r/maria-autozerofill.result
+++ b/mysql-test/suite/maria/r/maria-autozerofill.result
@@ -13,8 +13,7 @@ a
Warnings:
Error 1194 t1' is marked as crashed and should be repaired
flush table t1;
-Status: changed,sorted index pages,zerofilled,movable
-create_rename_lsn has magic value
+Status: changed,sorted index pages,zerofilled
insert into t1 values(2);
flush table t1;
create_rename_lsn has non-magic value
diff --git a/mysql-test/suite/maria/r/maria-recovery3.result b/mysql-test/suite/maria/r/maria-recovery3.result
index 12c3d0ae034..d71a3f6c00a 100644
--- a/mysql-test/suite/maria/r/maria-recovery3.result
+++ b/mysql-test/suite/maria/r/maria-recovery3.result
@@ -89,6 +89,28 @@ check table t1 extended;
Table Op Msg_type Msg_text
mysqltest.t1 check status OK
drop table t1;
+CREATE TABLE t1 ( word VARCHAR(255) PRIMARY KEY ) ENGINE=Aria;
+LOAD DATA INFILE '../../std_data/bug887051.txt' INTO TABLE t1;
+SET AUTOCOMMIT=0;
+DELETE FROM t1;
+LOAD DATA INFILE '../../std_data/bug887051.txt' INTO TABLE t1 IGNORE 1 LINES;
+COMMIT;
+SET SESSION debug_dbug="+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
+* 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
+failure
+use mysqltest;
+select * from t1;
+word
+saved2
+drop table t1;
drop database mysqltest_for_feeding_recovery;
drop database mysqltest_for_comparison;
drop database mysqltest;
diff --git a/mysql-test/suite/maria/t/compat_aliases-master.opt b/mysql-test/suite/maria/t/compat_aliases-master.opt
new file mode 100644
index 00000000000..a1dcde828cd
--- /dev/null
+++ b/mysql-test/suite/maria/t/compat_aliases-master.opt
@@ -0,0 +1 @@
+--maria-max-sort-file-size=100M --aria-repair-threads=100
diff --git a/mysql-test/suite/maria/t/maria-recovery3.test b/mysql-test/suite/maria/t/maria-recovery3.test
index 02babfccf83..e4bc73edc57 100644
--- a/mysql-test/suite/maria/t/maria-recovery3.test
+++ b/mysql-test/suite/maria/t/maria-recovery3.test
@@ -109,6 +109,24 @@ truncate table t1;
check table t1 extended;
drop table t1;
+#
+# Test for BUG#887051; Failure in recovery with delete
+#
+
+let $mvr_restore_old_snapshot=0;
+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;
+CREATE TABLE t1 ( word VARCHAR(255) PRIMARY KEY ) ENGINE=Aria;
+LOAD DATA INFILE '../../std_data/bug887051.txt' INTO TABLE t1;
+SET AUTOCOMMIT=0;
+DELETE FROM t1;
+LOAD DATA INFILE '../../std_data/bug887051.txt' INTO TABLE t1 IGNORE 1 LINES;
+COMMIT;
+-- source include/maria_verify_recovery.inc
+select * from t1;
+drop table t1;
+
# clean up everything
let $mms_purpose=feeding_recovery;
eval drop database mysqltest_for_$mms_purpose;
diff --git a/mysql-test/suite/pbxt/r/derived.result b/mysql-test/suite/pbxt/r/derived.result
index f2247504936..5cfa8c77cda 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
@@ -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 9 Using where
+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 9 Using where
+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;
@@ -387,3 +390,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 f821023f03a..aa4ba4bef06 100644
--- a/mysql-test/suite/pbxt/r/distinct.result
+++ b/mysql-test/suite/pbxt/r/distinct.result
@@ -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
@@ -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;
diff --git a/mysql-test/suite/pbxt/r/endspace.result b/mysql-test/suite/pbxt/r/endspace.result
index c9a2db8bbfe..641ed14023d 100644
--- a/mysql-test/suite/pbxt/r/endspace.result
+++ b/mysql-test/suite/pbxt/r/endspace.result
@@ -25,10 +25,11 @@ insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
-select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
+select * from t1 ignore key (key1) where text1='teststring' or
+text1 like 'teststring_%' ORDER BY text1;
text1
-teststring
teststring
+teststring
select * from t1 where text1='teststring' or text1 like 'teststring_%';
text1
teststring
@@ -48,10 +49,11 @@ alter table t1 modify text1 char(32) binary not null;
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
-select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
+select * from t1 ignore key (key1) where text1='teststring' or
+text1 like 'teststring_%' ORDER BY text1;
text1
-teststring
teststring
+teststring
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
concat('|', text1, '|')
|teststring |
@@ -132,10 +134,11 @@ concat('|', text1, '|')
drop table t1;
create table t1 (text1 varchar(32) not NULL, KEY key1 using BTREE (text1)) engine=heap;
insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
-select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
+select * from t1 ignore key (key1) where text1='teststring' or
+text1 like 'teststring_%' ORDER BY text1;
text1
-teststring
teststring
+teststring
select * from t1 where text1='teststring' or text1 like 'teststring_%';
text1
teststring
diff --git a/mysql-test/suite/pbxt/r/func_group.result b/mysql-test/suite/pbxt/r/func_group.result
index 1204b3c3981..4aca6dac1ed 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;
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/greedy_optimizer.result b/mysql-test/suite/pbxt/r/greedy_optimizer.result
index aeed76ab167..0dab29e2e59 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)
@@ -202,28 +204,28 @@ 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 (flat, BNL join)
+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 (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 (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 (flat, BNL join)
+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 (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 (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 Using where
@@ -231,11 +233,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -243,11 +245,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -255,11 +257,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -267,11 +269,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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
@@ -287,7 +289,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -299,7 +301,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -311,7 +313,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -323,7 +325,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -335,7 +337,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -347,35 +349,35 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
+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 (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 (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 (flat, BNL join)
+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 (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 (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 Using where
@@ -383,11 +385,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -395,11 +397,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -407,11 +409,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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 Using where
@@ -419,11 +421,11 @@ id select_type table type possible_keys key key_len ref rows Extra
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 (flat, BNL join)
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
@@ -443,7 +445,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -455,55 +457,55 @@ id select_type table type possible_keys key key_len ref rows Extra
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 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 (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 (flat, BNL join)
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 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 (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 (flat, BNL join)
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 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 (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 (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 (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
+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 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 (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 (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 (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
+Last_query_cost 844.825316
set optimizer_search_depth=1;
select @@optimizer_search_depth;
@@optimizer_search_depth
@@ -519,7 +521,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -531,7 +533,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -543,7 +545,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -555,7 +557,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -567,7 +569,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 Using where
@@ -579,7 +581,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -595,7 +597,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
@@ -607,53 +609,54 @@ id select_type table type possible_keys key key_len ref rows Extra
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 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 (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 (flat, BNL join)
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 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 (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 (flat, BNL join)
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 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 (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 (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 (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
+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 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 (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 (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 (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
+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 683a862b21e..034a95ecc71 100644
--- a/mysql-test/suite/pbxt/r/group_by.result
+++ b/mysql-test/suite/pbxt/r/group_by.result
@@ -451,6 +451,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
@@ -469,6 +471,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',
diff --git a/mysql-test/suite/pbxt/r/group_min_max.result b/mysql-test/suite/pbxt/r/group_min_max.result
index 6985abeeb43..820dd177ded 100644
--- a/mysql-test/suite/pbxt/r/group_min_max.result
+++ b/mysql-test/suite/pbxt/r/group_min_max.result
@@ -2258,7 +2258,7 @@ 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 <subquery2> ALL distinct_key NULL NULL NULL 15 Using where
1 PRIMARY t1_outer ref a a 5 <subquery2>.max(b) 1 Using index
-2 SUBQUERY t1 index NULL a 10 NULL 15 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
diff --git a/mysql-test/suite/pbxt/r/heap.result b/mysql-test/suite/pbxt/r/heap.result.THIS
index 0404e8b98f9..0404e8b98f9 100644
--- a/mysql-test/suite/pbxt/r/heap.result
+++ b/mysql-test/suite/pbxt/r/heap.result.THIS
diff --git a/mysql-test/suite/pbxt/r/join.result b/mysql-test/suite/pbxt/r/join.result
index 1a2b6e4fc80..bd47696bfdd 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);
@@ -799,7 +801,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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 1a195cb13a8..199e56ee150 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);
@@ -1614,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 496095680ce..a556049b8cc 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,
@@ -1198,3 +1200,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/select.result b/mysql-test/suite/pbxt/r/select.result
index 77630e5173b..a3ed13f3de0 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
@@ -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
@@ -3636,3 +3638,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 MariaDB 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/subselect.result b/mysql-test/suite/pbxt/r/subselect.result
index 02e1ed6c16a..fb4e93c57c8 100644
--- a/mysql-test/suite/pbxt/r/subselect.result
+++ b/mysql-test/suite/pbxt/r/subselect.result
@@ -196,6 +196,8 @@ 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
@@ -204,6 +206,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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
@@ -1264,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
@@ -1333,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
@@ -1360,9 +1365,9 @@ a
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; Start temporary
-1 PRIMARY t1 ref a a 5 test.t2.a 1 100.00 Using index
-1 PRIMARY t3 index a a 5 NULL 3 100.00 Using where; Using index; End temporary
+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` 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);
@@ -1381,6 +1386,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
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` 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);
@@ -1521,17 +1527,17 @@ 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
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <not>(<in_optimizer>(`test`.`t3`.`a`,(<max>(select `test`.`t2`.`b` from `test`.`t2` group by 1) > <cache>(`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
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(`test`.`t3`.`a`,(<min>(select `test`.`t2`.`b` from `test`.`t2` group by 1) <= <cache>(`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);
@@ -1545,9 +1551,9 @@ 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 ALL NULL NULL NULL NULL 0 0.00 Using temporary
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select `test`.`t2`.`b` from `test`.`t2` group by 1) <= NULL)))
+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);
@@ -1561,9 +1567,9 @@ 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 ALL NULL NULL NULL NULL 0 0.00 Using temporary
+2 SUBQUERY t2 ALL NULL NULL NULL NULL 0 0.00
Warnings:
-Note 1003 select `test`.`t3`.`a` AS `a` from `test`.`t3` where <nop>(<in_optimizer>(NULL,(<min>(select `test`.`t2`.`b` from `test`.`t2` group by 1) <= NULL)))
+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
@@ -2761,6 +2767,7 @@ max(fld)
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');
@@ -2836,15 +2843,15 @@ explain extended SELECT one,two from t1 where ROW(one,two) IN (SELECT one,two FR
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 10 func,func 1 100.00
-2 SUBQUERY t2 ALL NULL NULL NULL NULL 9 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` 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
+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') 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));
@@ -3429,7 +3436,7 @@ 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 23 test.t1.a,test.t1.b 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+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
@@ -3441,7 +3448,7 @@ 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 23 test.t1.a,test.t1.b 1
-2 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using temporary
+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);
@@ -4220,6 +4227,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');
@@ -4251,6 +4261,7 @@ id select_type table type possible_keys key key_len ref rows Extra
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
diff --git a/mysql-test/suite/pbxt/r/union.result b/mysql-test/suite/pbxt/r/union.result
index cea55f3f204..1d40c836fe9 100644
--- a/mysql-test/suite/pbxt/r/union.result
+++ b/mysql-test/suite/pbxt/r/union.result
@@ -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/view_grant.result b/mysql-test/suite/pbxt/r/view_grant.result.THIS
index cef441efc77..cef441efc77 100644
--- a/mysql-test/suite/pbxt/r/view_grant.result
+++ b/mysql-test/suite/pbxt/r/view_grant.result.THIS
diff --git a/mysql-test/suite/pbxt/t/derived.test b/mysql-test/suite/pbxt/t/derived.test
index 3a4f86563a1..aefdd72ae24 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;
@@ -286,3 +290,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/endspace.test b/mysql-test/suite/pbxt/t/endspace.test
index f2502640e71..a2962544a43 100644
--- a/mysql-test/suite/pbxt/t/endspace.test
+++ b/mysql-test/suite/pbxt/t/endspace.test
@@ -16,7 +16,8 @@ drop table if exists t1;
create table t1 (text1 varchar(32) not NULL, KEY key1 (text1));
insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
check table t1;
-select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
+select * from t1 ignore key (key1) where text1='teststring' or
+ text1 like 'teststring_%' ORDER BY text1;
select * from t1 where text1='teststring' or text1 like 'teststring_%';
select * from t1 where text1='teststring' or text1 > 'teststring\t';
select * from t1 order by text1;
@@ -24,7 +25,8 @@ explain select * from t1 order by text1;
alter table t1 modify text1 char(32) binary not null;
check table t1;
-select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
+select * from t1 ignore key (key1) where text1='teststring' or
+ text1 like 'teststring_%' ORDER BY text1;
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
select text1, length(text1) from t1 order by text1;
@@ -57,7 +59,8 @@ drop table t1;
create table t1 (text1 varchar(32) not NULL, KEY key1 using BTREE (text1)) engine=heap;
insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
-select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
+select * from t1 ignore key (key1) where text1='teststring' or
+ text1 like 'teststring_%' ORDER BY text1;
select * from t1 where text1='teststring' or text1 like 'teststring_%';
select * from t1 where text1='teststring' or text1 >= 'teststring\t';
select * from t1 order by text1;
@@ -97,7 +100,6 @@ select text1, length(text1) from t1 where text1='teststring' or text1 >= 'testst
select concat('|', text1, '|') from t1 order by text1;
drop table t1;
-
--disable_query_log
drop database pbxt;
--enable_query_log
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/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 46995ded550..76be09cd201 100644
--- a/mysql-test/suite/pbxt/t/group_by.test
+++ b/mysql-test/suite/pbxt/t/group_by.test
@@ -339,8 +339,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/heap.test b/mysql-test/suite/pbxt/t/heap.test.THIS
index 452bcb754d3..452bcb754d3 100644
--- a/mysql-test/suite/pbxt/t/heap.test
+++ b/mysql-test/suite/pbxt/t/heap.test.THIS
diff --git a/mysql-test/suite/pbxt/t/join.test b/mysql-test/suite/pbxt/t/join.test
index 02c17d8bcaa..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
#
@@ -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 98ffcbc9a8a..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);
@@ -1063,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/select.test b/mysql-test/suite/pbxt/t/select.test
index e870eb95fa4..ff455e6e90b 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
@@ -3135,6 +3138,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 651f47fcee1..3b49dfdebca 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);
@@ -829,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);
@@ -839,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;
#
@@ -1792,6 +1798,7 @@ 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));
@@ -3088,6 +3095,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');
@@ -3109,6 +3120,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
@@ -3223,6 +3235,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/union.test b/mysql-test/suite/pbxt/t/union.test
index a66aba0d46c..e324d824636 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/pbxt/t/view_grant.test b/mysql-test/suite/pbxt/t/view_grant.test.THIS
index 525d9423bb1..525d9423bb1 100644
--- a/mysql-test/suite/pbxt/t/view_grant.test
+++ b/mysql-test/suite/pbxt/t/view_grant.test.THIS
diff --git a/mysql-test/suite/percona/innodb_sys_index.result b/mysql-test/suite/percona/innodb_sys_index.result
new file mode 100644
index 00000000000..8bf4fa745ba
--- /dev/null
+++ b/mysql-test/suite/percona/innodb_sys_index.result
@@ -0,0 +1,17 @@
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 't1'
+select @@version_comment limit 1 ;
+@@version_comment
+Source distribution
+SELECT COUNT(*) FROM `information_schema`.`INNODB_SYS_INDEXES` ;
+CREATE TABLE test.t1 ( `a` SERIAL NOT NULL , `b` VARCHAR( 255 ) NOT NULL , INDEX ( `b` ) ) ENGINE = InnoDB ;
+SHOW TABLE STATUS FROM `information_schema` LIKE 'INNODB\_SYS\_INDEXES%' ;
+drop table test.t1;
+SHOW TABLE STATUS FROM `information_schema` LIKE 'INNODB\_SYS\_INDEXES%' ;
+SELECT COUNT(*) FROM `information_schema`.`INNODB_SYS_INDEXES` ;
+CREATE TABLE test.t1 ( `a` SERIAL NOT NULL , `b` VARCHAR( 255 ) NOT NULL , INDEX ( `b` ) ) ENGINE = InnoDB ;
+SHOW TABLE STATUS FROM `information_schema` LIKE 'INNODB\_SYS\_INDEXES%' ;
+SELECT COUNT(*) FROM `information_schema`.`INNODB_SYS_INDEXES` ;
+drop table test.t1;
+SHOW TABLE STATUS FROM `information_schema` LIKE 'INNODB\_SYS\_INDEXES%' ;
diff --git a/mysql-test/suite/percona/innodb_sys_index.test b/mysql-test/suite/percona/innodb_sys_index.test
new file mode 100644
index 00000000000..9b1ac4c87e8
--- /dev/null
+++ b/mysql-test/suite/percona/innodb_sys_index.test
@@ -0,0 +1,21 @@
+--source include/big_test.inc
+--source include/have_innodb.inc
+
+drop table if exists t1;
+#
+# test for bug LP#875797 "Using 'innodb_sys_indexes' causes core dump"
+#
+select @@version_comment limit 1 ;
+--disable_result_log
+SELECT COUNT(*) FROM `information_schema`.`INNODB_SYS_INDEXES` ;
+CREATE TABLE test.t1 ( `a` SERIAL NOT NULL , `b` VARCHAR( 255 ) NOT NULL , INDEX ( `b` ) ) ENGINE = InnoDB ;
+SHOW TABLE STATUS FROM `information_schema` LIKE 'INNODB\_SYS\_INDEXES%' ;
+drop table test.t1;
+SHOW TABLE STATUS FROM `information_schema` LIKE 'INNODB\_SYS\_INDEXES%' ;
+SELECT COUNT(*) FROM `information_schema`.`INNODB_SYS_INDEXES` ;
+CREATE TABLE test.t1 ( `a` SERIAL NOT NULL , `b` VARCHAR( 255 ) NOT NULL , INDEX ( `b` ) ) ENGINE = InnoDB ;
+SHOW TABLE STATUS FROM `information_schema` LIKE 'INNODB\_SYS\_INDEXES%' ;
+SELECT COUNT(*) FROM `information_schema`.`INNODB_SYS_INDEXES` ;
+drop table test.t1;
+SHOW TABLE STATUS FROM `information_schema` LIKE 'INNODB\_SYS\_INDEXES%' ;
+--enable_result_log
diff --git a/mysql-test/suite/perfschema/r/pfs_upgrade.result b/mysql-test/suite/perfschema/r/pfs_upgrade.result
index a7c47d8d64a..4d7d9e28fe8 100644
--- a/mysql-test/suite/perfschema/r/pfs_upgrade.result
+++ b/mysql-test/suite/perfschema/r/pfs_upgrade.result
@@ -8,24 +8,24 @@ use performance_schema;
show tables like "user_table";
Tables_in_performance_schema (user_table)
user_table
-ERROR 1050 (42S01) at line 182: Table 'cond_instances' already exists
-ERROR 1050 (42S01) at line 212: Table 'events_waits_current' already exists
-ERROR 1050 (42S01) at line 226: Table 'events_waits_history' already exists
-ERROR 1050 (42S01) at line 240: Table 'events_waits_history_long' already exists
-ERROR 1050 (42S01) at line 261: Table 'events_waits_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 282: Table 'events_waits_summary_by_thread_by_event_name' already exists
-ERROR 1050 (42S01) at line 302: Table 'events_waits_summary_global_by_event_name' already exists
-ERROR 1050 (42S01) at line 319: Table 'file_instances' already exists
-ERROR 1050 (42S01) at line 338: Table 'file_summary_by_event_name' already exists
-ERROR 1050 (42S01) at line 358: Table 'file_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 375: Table 'mutex_instances' already exists
-ERROR 1050 (42S01) at line 393: Table 'performance_timers' already exists
-ERROR 1050 (42S01) at line 411: Table 'rwlock_instances' already exists
-ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
-ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
-ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
-ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists
+ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists
+ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists
+ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists
+ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists
+ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists
+ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists
+ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists
+ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists
+ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists
+ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists
+ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists
+ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists
+ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists
+ERROR 1050 (42S01) at line 478: Table 'threads' already exists
+ERROR 1644 (HY000) at line 1126: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
show tables like "user_table";
Tables_in_performance_schema (user_table)
@@ -38,24 +38,24 @@ use performance_schema;
show tables like "user_view";
Tables_in_performance_schema (user_view)
user_view
-ERROR 1050 (42S01) at line 182: Table 'cond_instances' already exists
-ERROR 1050 (42S01) at line 212: Table 'events_waits_current' already exists
-ERROR 1050 (42S01) at line 226: Table 'events_waits_history' already exists
-ERROR 1050 (42S01) at line 240: Table 'events_waits_history_long' already exists
-ERROR 1050 (42S01) at line 261: Table 'events_waits_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 282: Table 'events_waits_summary_by_thread_by_event_name' already exists
-ERROR 1050 (42S01) at line 302: Table 'events_waits_summary_global_by_event_name' already exists
-ERROR 1050 (42S01) at line 319: Table 'file_instances' already exists
-ERROR 1050 (42S01) at line 338: Table 'file_summary_by_event_name' already exists
-ERROR 1050 (42S01) at line 358: Table 'file_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 375: Table 'mutex_instances' already exists
-ERROR 1050 (42S01) at line 393: Table 'performance_timers' already exists
-ERROR 1050 (42S01) at line 411: Table 'rwlock_instances' already exists
-ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
-ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
-ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
-ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists
+ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists
+ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists
+ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists
+ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists
+ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists
+ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists
+ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists
+ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists
+ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists
+ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists
+ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists
+ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists
+ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists
+ERROR 1050 (42S01) at line 478: Table 'threads' already exists
+ERROR 1644 (HY000) at line 1126: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
show tables like "user_view";
Tables_in_performance_schema (user_view)
@@ -66,24 +66,24 @@ drop view test.user_view;
create procedure test.user_proc()
select "Not supposed to be here";
update mysql.proc set db='performance_schema' where name='user_proc';
-ERROR 1050 (42S01) at line 182: Table 'cond_instances' already exists
-ERROR 1050 (42S01) at line 212: Table 'events_waits_current' already exists
-ERROR 1050 (42S01) at line 226: Table 'events_waits_history' already exists
-ERROR 1050 (42S01) at line 240: Table 'events_waits_history_long' already exists
-ERROR 1050 (42S01) at line 261: Table 'events_waits_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 282: Table 'events_waits_summary_by_thread_by_event_name' already exists
-ERROR 1050 (42S01) at line 302: Table 'events_waits_summary_global_by_event_name' already exists
-ERROR 1050 (42S01) at line 319: Table 'file_instances' already exists
-ERROR 1050 (42S01) at line 338: Table 'file_summary_by_event_name' already exists
-ERROR 1050 (42S01) at line 358: Table 'file_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 375: Table 'mutex_instances' already exists
-ERROR 1050 (42S01) at line 393: Table 'performance_timers' already exists
-ERROR 1050 (42S01) at line 411: Table 'rwlock_instances' already exists
-ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
-ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
-ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
-ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists
+ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists
+ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists
+ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists
+ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists
+ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists
+ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists
+ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists
+ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists
+ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists
+ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists
+ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists
+ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists
+ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists
+ERROR 1050 (42S01) at line 478: Table 'threads' already exists
+ERROR 1644 (HY000) at line 1126: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
select name from mysql.proc where db='performance_schema';
name
@@ -94,24 +94,24 @@ drop procedure test.user_proc;
create function test.user_func() returns integer
return 0;
update mysql.proc set db='performance_schema' where name='user_func';
-ERROR 1050 (42S01) at line 182: Table 'cond_instances' already exists
-ERROR 1050 (42S01) at line 212: Table 'events_waits_current' already exists
-ERROR 1050 (42S01) at line 226: Table 'events_waits_history' already exists
-ERROR 1050 (42S01) at line 240: Table 'events_waits_history_long' already exists
-ERROR 1050 (42S01) at line 261: Table 'events_waits_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 282: Table 'events_waits_summary_by_thread_by_event_name' already exists
-ERROR 1050 (42S01) at line 302: Table 'events_waits_summary_global_by_event_name' already exists
-ERROR 1050 (42S01) at line 319: Table 'file_instances' already exists
-ERROR 1050 (42S01) at line 338: Table 'file_summary_by_event_name' already exists
-ERROR 1050 (42S01) at line 358: Table 'file_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 375: Table 'mutex_instances' already exists
-ERROR 1050 (42S01) at line 393: Table 'performance_timers' already exists
-ERROR 1050 (42S01) at line 411: Table 'rwlock_instances' already exists
-ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
-ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
-ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
-ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists
+ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists
+ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists
+ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists
+ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists
+ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists
+ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists
+ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists
+ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists
+ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists
+ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists
+ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists
+ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists
+ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists
+ERROR 1050 (42S01) at line 478: Table 'threads' already exists
+ERROR 1644 (HY000) at line 1126: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
select name from mysql.proc where db='performance_schema';
name
@@ -122,24 +122,24 @@ drop function test.user_func;
create event test.user_event on schedule every 1 day do
select "not supposed to be here";
update mysql.event set db='performance_schema' where name='user_event';
-ERROR 1050 (42S01) at line 182: Table 'cond_instances' already exists
-ERROR 1050 (42S01) at line 212: Table 'events_waits_current' already exists
-ERROR 1050 (42S01) at line 226: Table 'events_waits_history' already exists
-ERROR 1050 (42S01) at line 240: Table 'events_waits_history_long' already exists
-ERROR 1050 (42S01) at line 261: Table 'events_waits_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 282: Table 'events_waits_summary_by_thread_by_event_name' already exists
-ERROR 1050 (42S01) at line 302: Table 'events_waits_summary_global_by_event_name' already exists
-ERROR 1050 (42S01) at line 319: Table 'file_instances' already exists
-ERROR 1050 (42S01) at line 338: Table 'file_summary_by_event_name' already exists
-ERROR 1050 (42S01) at line 358: Table 'file_summary_by_instance' already exists
-ERROR 1050 (42S01) at line 375: Table 'mutex_instances' already exists
-ERROR 1050 (42S01) at line 393: Table 'performance_timers' already exists
-ERROR 1050 (42S01) at line 411: Table 'rwlock_instances' already exists
-ERROR 1050 (42S01) at line 427: Table 'setup_consumers' already exists
-ERROR 1050 (42S01) at line 444: Table 'setup_instruments' already exists
-ERROR 1050 (42S01) at line 460: Table 'setup_timers' already exists
-ERROR 1050 (42S01) at line 477: Table 'threads' already exists
-ERROR 1644 (HY000) at line 1125: Unexpected content found in the performance_schema database.
+ERROR 1050 (42S01) at line 183: Table 'cond_instances' already exists
+ERROR 1050 (42S01) at line 213: Table 'events_waits_current' already exists
+ERROR 1050 (42S01) at line 227: Table 'events_waits_history' already exists
+ERROR 1050 (42S01) at line 241: Table 'events_waits_history_long' already exists
+ERROR 1050 (42S01) at line 262: Table 'events_waits_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 283: Table 'events_waits_summary_by_thread_by_event_name' already exists
+ERROR 1050 (42S01) at line 303: Table 'events_waits_summary_global_by_event_name' already exists
+ERROR 1050 (42S01) at line 320: Table 'file_instances' already exists
+ERROR 1050 (42S01) at line 339: Table 'file_summary_by_event_name' already exists
+ERROR 1050 (42S01) at line 359: Table 'file_summary_by_instance' already exists
+ERROR 1050 (42S01) at line 376: Table 'mutex_instances' already exists
+ERROR 1050 (42S01) at line 394: Table 'performance_timers' already exists
+ERROR 1050 (42S01) at line 412: Table 'rwlock_instances' already exists
+ERROR 1050 (42S01) at line 428: Table 'setup_consumers' already exists
+ERROR 1050 (42S01) at line 445: Table 'setup_instruments' already exists
+ERROR 1050 (42S01) at line 461: Table 'setup_timers' already exists
+ERROR 1050 (42S01) at line 478: Table 'threads' already exists
+ERROR 1644 (HY000) at line 1126: Unexpected content found in the performance_schema database.
FATAL ERROR: Upgrade failed
select name from mysql.event where db='performance_schema';
name
diff --git a/mysql-test/suite/plugins/r/dialog.result b/mysql-test/suite/plugins/r/dialog.result
new file mode 100644
index 00000000000..0fcbb41ebe0
--- /dev/null
+++ b/mysql-test/suite/plugins/r/dialog.result
@@ -0,0 +1,26 @@
+install plugin three_attempts soname 'dialog_examples.so';
+create user test_dialog identified via three_attempts using 'SECRET';
+#
+# -pSECRET is picked up, no questions asked.
+#
+select user(), current_user();
+user() current_user()
+test_dialog@localhost test_dialog@%
+#
+# without -p. up to three questions are asked on the stdin.
+# athentication is successful, the correct pasword is on the third line
+#
+Password, please: ***
+Password, please: ****
+Password, please: ******
+select user(), current_user();
+user() current_user()
+test_dialog@localhost test_dialog@%
+#
+# athentication is unsuccessful, first three lines are all wrong
+#
+Password, please: ***
+Password, please: ****
+Password, please: *****
+drop user test_dialog;
+uninstall plugin three_attempts;
diff --git a/mysql-test/r/feedback_plugin_install.result b/mysql-test/suite/plugins/r/feedback_plugin_install.result
index b1b35072a08..b1b35072a08 100644
--- a/mysql-test/r/feedback_plugin_install.result
+++ b/mysql-test/suite/plugins/r/feedback_plugin_install.result
diff --git a/mysql-test/r/feedback_plugin_load.result b/mysql-test/suite/plugins/r/feedback_plugin_load.result
index d434d1282c5..d434d1282c5 100644
--- a/mysql-test/r/feedback_plugin_load.result
+++ b/mysql-test/suite/plugins/r/feedback_plugin_load.result
diff --git a/mysql-test/r/feedback_plugin_send.result b/mysql-test/suite/plugins/r/feedback_plugin_send.result
index db622cb3f97..db622cb3f97 100644
--- a/mysql-test/r/feedback_plugin_send.result
+++ b/mysql-test/suite/plugins/r/feedback_plugin_send.result
diff --git a/mysql-test/r/fulltext_plugin.result b/mysql-test/suite/plugins/r/fulltext_plugin.result
index 69ebbe07e9e..69ebbe07e9e 100644
--- a/mysql-test/r/fulltext_plugin.result
+++ b/mysql-test/suite/plugins/r/fulltext_plugin.result
diff --git a/mysql-test/suite/plugins/r/pam.result b/mysql-test/suite/plugins/r/pam.result
new file mode 100644
index 00000000000..1c9036c317e
--- /dev/null
+++ b/mysql-test/suite/plugins/r/pam.result
@@ -0,0 +1,22 @@
+install plugin pam soname 'auth_pam.so';
+create user test_pam identified via pam using 'mariadb_mtr';
+#
+# athentication is successful, challenge/pin are ok
+# note that current_user() differts from user()
+#
+Challenge input first.
+Enter: not very secret challenge
+Now, the magic number!
+PIN: ****
+select user(), current_user(), database();
+user() current_user() database()
+test_pam@localhost pam_test@% test
+#
+# athentication is unsuccessful
+#
+Challenge input first.
+Enter: not very secret challenge
+Now, the magic number!
+PIN: ****
+drop user test_pam;
+uninstall plugin pam;
diff --git a/mysql-test/suite/plugins/suite.pm b/mysql-test/suite/plugins/suite.pm
new file mode 100644
index 00000000000..f8f78086c15
--- /dev/null
+++ b/mysql-test/suite/plugins/suite.pm
@@ -0,0 +1,8 @@
+package My::Suite::Plugins;
+
+@ISA = qw(My::Suite);
+
+$ENV{PAM_SETUP_FOR_MTR}=1 if -e '/etc/pam.d/mariadb_mtr';
+
+bless { };
+
diff --git a/mysql-test/suite/plugins/t/dialog.test b/mysql-test/suite/plugins/t/dialog.test
new file mode 100644
index 00000000000..0507686acf3
--- /dev/null
+++ b/mysql-test/suite/plugins/t/dialog.test
@@ -0,0 +1,54 @@
+#
+# test for the client "dialog" plugin
+#
+
+--source include/not_embedded.inc
+
+if (!$DIALOG_SO) {
+ skip No dialog auth plugin;
+}
+if (!$DIALOG_EXAMPLES_SO) {
+ skip No dialog auth plugin;
+}
+
+--replace_result .dll .so
+eval install plugin three_attempts soname '$DIALOG_EXAMPLES_SO';
+create user test_dialog identified via three_attempts using 'SECRET';
+
+let $plugindir=`SELECT @@global.plugin_dir`;
+
+--write_file $MYSQLTEST_VARDIR/tmp/dialog_good.txt
+foo
+1234
+SECRET
+select user(), current_user();
+EOF
+
+--write_file $MYSQLTEST_VARDIR/tmp/dialog_bad.txt
+foo
+1234
+wrong
+SECRET
+EOF
+
+--echo #
+--echo # -pSECRET is picked up, no questions asked.
+--echo #
+--exec echo "select user(), current_user();"|$MYSQL_TEST -u test_dialog -pSECRET --plugin-dir=$plugindir
+
+--echo #
+--echo # without -p. up to three questions are asked on the stdin.
+--echo # athentication is successful, the correct pasword is on the third line
+--echo #
+--exec $MYSQL_TEST -u test_dialog --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/dialog_good.txt
+
+--echo #
+--echo # athentication is unsuccessful, first three lines are all wrong
+--echo #
+--error 1
+--exec $MYSQL_TEST -u test_dialog --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/dialog_bad.txt
+
+--remove_file $MYSQLTEST_VARDIR/tmp/dialog_good.txt
+--remove_file $MYSQLTEST_VARDIR/tmp/dialog_bad.txt
+drop user test_dialog;
+uninstall plugin three_attempts;
diff --git a/mysql-test/t/feedback_plugin_install.opt b/mysql-test/suite/plugins/t/feedback_plugin_install.opt
index a711ae94e69..a711ae94e69 100644
--- a/mysql-test/t/feedback_plugin_install.opt
+++ b/mysql-test/suite/plugins/t/feedback_plugin_install.opt
diff --git a/mysql-test/t/feedback_plugin_install.test b/mysql-test/suite/plugins/t/feedback_plugin_install.test
index 81343c436c3..81343c436c3 100644
--- a/mysql-test/t/feedback_plugin_install.test
+++ b/mysql-test/suite/plugins/t/feedback_plugin_install.test
diff --git a/mysql-test/t/feedback_plugin_load.opt b/mysql-test/suite/plugins/t/feedback_plugin_load.opt
index 5fbb2f83954..5fbb2f83954 100644
--- a/mysql-test/t/feedback_plugin_load.opt
+++ b/mysql-test/suite/plugins/t/feedback_plugin_load.opt
diff --git a/mysql-test/t/feedback_plugin_load.test b/mysql-test/suite/plugins/t/feedback_plugin_load.test
index 5ad301667b4..5ad301667b4 100644
--- a/mysql-test/t/feedback_plugin_load.test
+++ b/mysql-test/suite/plugins/t/feedback_plugin_load.test
diff --git a/mysql-test/t/feedback_plugin_send.test b/mysql-test/suite/plugins/t/feedback_plugin_send.test
index 14765ee9543..3324ef469fe 100644
--- a/mysql-test/t/feedback_plugin_send.test
+++ b/mysql-test/suite/plugins/t/feedback_plugin_send.test
@@ -1,4 +1,4 @@
-source t/feedback_plugin_load.test;
+source feedback_plugin_load.test;
if (!$MTR_FEEDBACK_PLUGIN) {
skip MTR_FEEDBACK_PLUGIN is not set;
@@ -17,7 +17,16 @@ replace_result https http;
perl;
$log_error= $ENV{'MYSQLTEST_VARDIR'} . '/log/mysqld.1.err';
open(LOG, '<', $log_error) or die "open(< $log_error): $!";
- /feedback plugin:.*/ && print "$&\n" while $_=<LOG>;
+
+ # Get the first few rows (as there may be different number rows in the log)
+ $i= 0;
+ while ($_=<LOG>)
+ {
+ if (/feedback plugin:.*/)
+ {
+ print "$&\n";
+ break if ($i++ >= 3);
+ }
+ }
close LOG;
EOF
-
diff --git a/mysql-test/t/fulltext_plugin.test b/mysql-test/suite/plugins/t/fulltext_plugin.test
index 0e2f53d5b15..0e2f53d5b15 100644
--- a/mysql-test/t/fulltext_plugin.test
+++ b/mysql-test/suite/plugins/t/fulltext_plugin.test
diff --git a/mysql-test/suite/plugins/t/pam.test b/mysql-test/suite/plugins/t/pam.test
new file mode 100644
index 00000000000..3f4c563d8dc
--- /dev/null
+++ b/mysql-test/suite/plugins/t/pam.test
@@ -0,0 +1,46 @@
+
+--source include/not_embedded.inc
+
+if (!$AUTH_PAM_SO) {
+ skip No pam auth plugin;
+}
+
+if (!$PAM_SETUP_FOR_MTR) {
+ skip No pam setup for mtr;
+}
+
+--replace_result .dll .so
+eval install plugin pam soname '$AUTH_PAM_SO';
+create user test_pam identified via pam using 'mariadb_mtr';
+
+let $plugindir=`SELECT @@global.plugin_dir`;
+
+--write_file $MYSQLTEST_VARDIR/tmp/pam_good.txt
+not very secret challenge
+9225
+select user(), current_user(), database();
+EOF
+
+--write_file $MYSQLTEST_VARDIR/tmp/pam_bad.txt
+not very secret challenge
+9224
+select user(), current_user(), database();
+EOF
+
+--echo #
+--echo # athentication is successful, challenge/pin are ok
+--echo # note that current_user() differts from user()
+--echo #
+--exec $MYSQL_TEST -u test_pam --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_good.txt
+
+--echo #
+--echo # athentication is unsuccessful
+--echo #
+--error 1
+--exec $MYSQL_TEST -u test_pam --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/pam_bad.txt
+
+--remove_file $MYSQLTEST_VARDIR/tmp/pam_good.txt
+--remove_file $MYSQLTEST_VARDIR/tmp/pam_bad.txt
+drop user test_pam;
+uninstall plugin pam;
+
diff --git a/mysql-test/suite/sys_vars/r/aria_recover_basic.result b/mysql-test/suite/sys_vars/r/aria_recover_basic.result
index ec275449c22..9cbc6617874 100644
--- a/mysql-test/suite/sys_vars/r/aria_recover_basic.result
+++ b/mysql-test/suite/sys_vars/r/aria_recover_basic.result
@@ -34,11 +34,15 @@ set global aria_recover='force';
select @@global.aria_recover;
@@global.aria_recover
FORCE
-set global aria_recover='quick';
+set global aria_recover=off;
select @@global.aria_recover;
@@global.aria_recover
-QUICK
-set global aria_recover=off;
+OFF
+set global aria_recover='quick,force';
+select @@global.aria_recover;
+@@global.aria_recover
+FORCE,QUICK
+set global aria_recover=16;
select @@global.aria_recover;
@@global.aria_recover
OFF
@@ -48,6 +52,6 @@ set global aria_recover=1e1;
ERROR 42000: Incorrect argument type to variable 'aria_recover'
set global aria_recover="foo";
ERROR 42000: Variable 'aria_recover' can't be set to the value of 'foo'
-set global aria_recover=5;
-ERROR 42000: Variable 'aria_recover' can't be set to the value of '5'
+set global aria_recover=32;
+ERROR 42000: Variable 'aria_recover' can't be set to the value of '32'
SET @@global.aria_recover = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/r/aria_repair_threads_basic.result b/mysql-test/suite/sys_vars/r/aria_repair_threads_basic.result
index 947dc182fc0..10d57aad1b0 100644
--- a/mysql-test/suite/sys_vars/r/aria_repair_threads_basic.result
+++ b/mysql-test/suite/sys_vars/r/aria_repair_threads_basic.result
@@ -41,7 +41,8 @@ set session aria_repair_threads=cast(-1 as unsigned int);
Warnings:
Note 1105 Cast to unsigned converted negative integer to it's positive complement
Note 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1292 Truncated incorrect aria_repair_threads value: '18446744073709551615'
select @@session.aria_repair_threads;
@@session.aria_repair_threads
-18446744073709551615
+128
SET @@global.aria_repair_threads = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/r/aria_sort_buffer_size_basic.result b/mysql-test/suite/sys_vars/r/aria_sort_buffer_size_basic.result
index 4d4fba9a543..0e0a2429f41 100644
--- a/mysql-test/suite/sys_vars/r/aria_sort_buffer_size_basic.result
+++ b/mysql-test/suite/sys_vars/r/aria_sort_buffer_size_basic.result
@@ -41,7 +41,8 @@ set session aria_sort_buffer_size=cast(-1 as unsigned int);
Warnings:
Note 1105 Cast to unsigned converted negative integer to it's positive complement
Note 1105 Cast to unsigned converted negative integer to it's positive complement
+Warning 1292 Truncated incorrect aria_sort_buffer_size value: '18446744073709551615'
select @@session.aria_sort_buffer_size;
@@session.aria_sort_buffer_size
-18446744073709551615
+4294967295
SET @@global.aria_sort_buffer_size = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result b/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result
index 28b57da381d..867941d987b 100644
--- a/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result
+++ b/mysql-test/suite/sys_vars/r/engine_condition_pushdown_basic.result
@@ -9,7 +9,7 @@ SELECT @global_start_value;
select @old_session_opt_switch:=@@session.optimizer_switch,
@old_global_opt_switch:=@@global.optimizer_switch;
@old_session_opt_switch:=@@session.optimizer_switch @old_global_opt_switch:=@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
'#--------------------FN_DYNVARS_028_01------------------------#'
SET @@session.engine_condition_pushdown = 0;
Warnings:
@@ -212,7 +212,7 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
set @@session.engine_condition_pushdown = TRUE;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 7.0. Please use '@@optimizer_switch' instead
@@ -220,7 +220,7 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-1 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+1 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
set @@session.engine_condition_pushdown = FALSE;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 7.0. Please use '@@optimizer_switch' instead
@@ -228,7 +228,7 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
set @@global.engine_condition_pushdown = TRUE;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 7.0. Please use '@@optimizer_switch' instead
@@ -236,7 +236,7 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+0 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=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
set @@global.engine_condition_pushdown = FALSE;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 7.0. Please use '@@optimizer_switch' instead
@@ -244,31 +244,31 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
set @@session.optimizer_switch = "engine_condition_pushdown=on";
select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-1 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+1 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
set @@session.optimizer_switch = "engine_condition_pushdown=off";
select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
set @@global.optimizer_switch = "engine_condition_pushdown=on";
select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+0 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=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
set @@global.optimizer_switch = "engine_condition_pushdown=off";
select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
SET @@session.engine_condition_pushdown = @session_start_value;
Warnings:
Warning 1287 The syntax '@@engine_condition_pushdown' is deprecated and will be removed in MariaDB 7.0. Please use '@@optimizer_switch' instead
@@ -287,4 +287,4 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
diff --git a/mysql-test/suite/sys_vars/r/join_cache_level_basic.result b/mysql-test/suite/sys_vars/r/join_cache_level_basic.result
index 871a8a28c39..eca823a5d72 100644
--- a/mysql-test/suite/sys_vars/r/join_cache_level_basic.result
+++ b/mysql-test/suite/sys_vars/r/join_cache_level_basic.result
@@ -1,22 +1,22 @@
SET @start_global_value = @@global.join_cache_level;
select @@global.join_cache_level;
@@global.join_cache_level
-1
+2
select @@session.join_cache_level;
@@session.join_cache_level
-1
+2
show global variables like 'join_cache_level';
Variable_name Value
-join_cache_level 1
+join_cache_level 2
show session variables like 'join_cache_level';
Variable_name Value
-join_cache_level 1
+join_cache_level 2
select * from information_schema.global_variables where variable_name='join_cache_level';
VARIABLE_NAME VARIABLE_VALUE
-JOIN_CACHE_LEVEL 1
+JOIN_CACHE_LEVEL 2
select * from information_schema.session_variables where variable_name='join_cache_level';
VARIABLE_NAME VARIABLE_VALUE
-JOIN_CACHE_LEVEL 1
+JOIN_CACHE_LEVEL 2
set global join_cache_level=4;
select @@global.join_cache_level;
@@global.join_cache_level
diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
index db768c4a25f..879015fc456 100644
--- a/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_basic.result
@@ -1,25 +1,25 @@
SET @start_global_value = @@global.optimizer_switch;
SELECT @start_global_value;
@start_global_value
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
select @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
select @@session.optimizer_switch;
@@session.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
show global variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
show session variables like 'optimizer_switch';
Variable_name Value
-optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
select * from information_schema.global_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
select * from information_schema.session_variables where variable_name='optimizer_switch';
VARIABLE_NAME VARIABLE_VALUE
-OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+OPTIMIZER_SWITCH index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
set global optimizer_switch=10;
set session optimizer_switch=5;
select @@global.optimizer_switch;
@@ -63,4 +63,4 @@ ERROR 42000: Variable 'optimizer_switch' can't be set to the value of 'foobar'
SET @@global.optimizer_switch = @start_global_value;
SELECT @@global.optimizer_switch;
@@global.optimizer_switch
-index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown1.result b/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown1.result
index 5e3af75378f..0b747ada48c 100644
--- a/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown1.result
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown1.result
@@ -2,4 +2,4 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-1 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+1 1 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=on,index_condition_pushdown=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
diff --git a/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown2.result b/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown2.result
index 5adcf99675d..aca4167b5be 100644
--- a/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown2.result
+++ b/mysql-test/suite/sys_vars/r/optimizer_switch_eng_cond_pushdown2.result
@@ -2,4 +2,4 @@ select @@session.engine_condition_pushdown,
@@global.engine_condition_pushdown,
@@session.optimizer_switch, @@global.optimizer_switch;
@@session.engine_condition_pushdown @@global.engine_condition_pushdown @@session.optimizer_switch @@global.optimizer_switch
-0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=on,derived_merge=off,derived_with_keys=off,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=off,semijoin_with_cache=off,join_cache_incremental=on,join_cache_hashed=on,join_cache_bka=on,optimize_join_buffer_size=off,table_elimination=on
+0 0 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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 index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off,engine_condition_pushdown=off,index_condition_pushdown=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
diff --git a/mysql-test/suite/sys_vars/r/sql_big_tables_func.result b/mysql-test/suite/sys_vars/r/sql_big_tables_func.result
index 9b707e439ef..cf42cb742b2 100644
--- a/mysql-test/suite/sys_vars/r/sql_big_tables_func.result
+++ b/mysql-test/suite/sys_vars/r/sql_big_tables_func.result
@@ -11,34 +11,9 @@ INSERT INTO t1 VALUES('aa','bb');
SET SESSION sql_big_tables = 1;
SET @diskTableCount = 0;
SET @tempTableCount = 0;
-SELECT * FROM (SELECT ta.a as a, tb.b as b
-FROM t1 as ta INNER JOIN t1 as tb ON ta.a = tb.a) sub;
-a b
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
-aa bb
+select count(a), b from t1 group by b;
+count(a) b
+5 bb
SET @diskTableCount = 1 - @diskTableCount;
SET @tempTableCount = 1 - @tempTableCount;
SELECT @diskTableCount;
diff --git a/mysql-test/suite/sys_vars/t/aria_recover_basic.test b/mysql-test/suite/sys_vars/t/aria_recover_basic.test
index 25aa2d7cf77..42e280b0499 100644
--- a/mysql-test/suite/sys_vars/t/aria_recover_basic.test
+++ b/mysql-test/suite/sys_vars/t/aria_recover_basic.test
@@ -1,4 +1,4 @@
-# enum global
+# set global
--source include/have_maria.inc
SET @start_global_value = @@global.aria_recover;
@@ -23,7 +23,7 @@ select @@global.aria_recover;
set session aria_recover=1;
#
-# all valid values
+# valid values
#
set global aria_recover=normal;
select @@global.aria_recover;
@@ -31,10 +31,12 @@ set global aria_recover=backup;
select @@global.aria_recover;
set global aria_recover='force';
select @@global.aria_recover;
-set global aria_recover='quick';
-select @@global.aria_recover;
set global aria_recover=off;
select @@global.aria_recover;
+set global aria_recover='quick,force';
+select @@global.aria_recover;
+set global aria_recover=16;
+select @@global.aria_recover;
#
# incorrect types/values
@@ -46,6 +48,6 @@ set global aria_recover=1e1;
--error ER_WRONG_VALUE_FOR_VAR
set global aria_recover="foo";
--error ER_WRONG_VALUE_FOR_VAR
-set global aria_recover=5;
+set global aria_recover=32;
SET @@global.aria_recover = @start_global_value;
diff --git a/mysql-test/suite/sys_vars/t/sql_big_tables_func.test b/mysql-test/suite/sys_vars/t/sql_big_tables_func.test
index 5f919fac2c7..8bbec202efa 100644
--- a/mysql-test/suite/sys_vars/t/sql_big_tables_func.test
+++ b/mysql-test/suite/sys_vars/t/sql_big_tables_func.test
@@ -55,8 +55,7 @@ let $totalTablesBig = query_get_value(SHOW STATUS LIKE 'Created_tmp_tables', Val
eval SET @diskTableCount = $diskTablesBig;
eval SET @tempTableCount = $totalTablesBig;
-SELECT * FROM (SELECT ta.a as a, tb.b as b
-FROM t1 as ta INNER JOIN t1 as tb ON ta.a = tb.a) sub;
+select count(a), b from t1 group by b;
let $newDiskTablesBig = query_get_value(SHOW STATUS LIKE 'Created_tmp_disk_tables', Value, 1);
let $newTotalTablesBig = query_get_value(SHOW STATUS LIKE 'Created_tmp_tables', Value, 1);
diff --git a/mysql-test/suite/vcol/inc/vcol_keys.inc b/mysql-test/suite/vcol/inc/vcol_keys.inc
index bba58363a81..6d859a4b0c3 100644
--- a/mysql-test/suite/vcol/inc/vcol_keys.inc
+++ b/mysql-test/suite/vcol/inc/vcol_keys.inc
@@ -98,7 +98,7 @@ if (!$skip_spatial_index_check)
--error ER_SPATIAL_CANT_HAVE_NULL
create table t1 (a int, b geometry as (a+1) persistent, spatial index (b));
create table t1 (a int, b int as (a+1) persistent);
- --error ER_SPATIAL_MUST_HAVE_GEOM_COL
+ --error ER_WRONG_ARGUMENTS
alter table t1 add spatial index (b);
drop table t1;
}
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 64149a7bb31..abbeda60b75 100644
--- a/mysql-test/suite/vcol/inc/vcol_view.inc
+++ b/mysql-test/suite/vcol/inc/vcol_view.inc
@@ -106,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,
@@ -119,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_keys_myisam.result b/mysql-test/suite/vcol/r/vcol_keys_myisam.result
index bed28b9aa49..dccdf7f73e5 100644
--- a/mysql-test/suite/vcol/r/vcol_keys_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_keys_myisam.result
@@ -104,7 +104,7 @@ create table t1 (a int, b geometry as (a+1) persistent, spatial index (b));
ERROR 42000: All parts of a SPATIAL index must be NOT NULL
create table t1 (a int, b int as (a+1) persistent);
alter table t1 add spatial index (b);
-ERROR 42000: A SPATIAL index may only contain a geometrical type column
+ERROR HY000: Incorrect arguments to SPATIAL INDEX
drop table t1;
# FOREIGN KEY
# Rejected FK options.
diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result
index 0d8f1f03db3..f587520f6aa 100644
--- a/mysql-test/suite/vcol/r/vcol_select_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result
@@ -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
###
diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result
index 22305a21c43..d4868340ab5 100644
--- a/mysql-test/suite/vcol/r/vcol_select_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result
@@ -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
###
diff --git a/mysql-test/suite/vcol/r/vcol_view_innodb.result b/mysql-test/suite/vcol/r/vcol_view_innodb.result
index 195808d5adb..fe666e0e400 100644
--- a/mysql-test/suite/vcol/r/vcol_view_innodb.result
+++ b/mysql-test/suite/vcol/r/vcol_view_innodb.result
@@ -154,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,
@@ -174,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 e017b1e458b..78c20f79f5e 100644
--- a/mysql-test/suite/vcol/r/vcol_view_myisam.result
+++ b/mysql-test/suite/vcol/r/vcol_view_myisam.result
@@ -154,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,
@@ -174,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/t/archive.test b/mysql-test/t/archive.test
index bb6b4ec9c17..80f88fbb51b 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1664,6 +1664,8 @@ SELECT * FROM t1;
INSERT INTO t1 (col1, col2) VALUES (1, "value");
REPAIR TABLE t1;
+SHOW CREATE TABLE t1;
+SELECT * FROM t1;
DROP TABLE t1;
remove_file $MYSQLD_DATADIR/test/t1.ARM;
diff --git a/mysql-test/t/auth_rpl-master.opt b/mysql-test/t/auth_rpl-master.opt
index 3536d102387..ff91abb1bef 100644
--- a/mysql-test/t/auth_rpl-master.opt
+++ b/mysql-test/t/auth_rpl-master.opt
@@ -1,2 +1 @@
-$PLUGIN_AUTH_OPT
-$PLUGIN_AUTH_LOAD
+--plugin-load=$AUTH_TEST_PLUGIN_SO
diff --git a/mysql-test/t/auth_rpl-slave.opt b/mysql-test/t/auth_rpl-slave.opt
index 3f4af6e59bb..ca6eee95ded 100644
--- a/mysql-test/t/auth_rpl-slave.opt
+++ b/mysql-test/t/auth_rpl-slave.opt
@@ -1,4 +1,2 @@
--master-retry-count=1
-$PLUGIN_AUTH_OPT
-$PLUGIN_AUTH_LOAD
-
+--plugin-load=$AUTH_TEST_PLUGIN_SO
diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test
index f5e2bc9ea57..c8a5c968fe5 100644
--- a/mysql-test/t/cast.test
+++ b/mysql-test/t/cast.test
@@ -394,6 +394,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;
diff --git a/mysql-test/t/derived.test b/mysql-test/t/derived.test
index 6cc3db739f6..4cf5cccc254 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;
@@ -338,3 +342,4 @@ SELECT 1 FROM t1 JOIN v1 ON 1 > (SELECT 1 FROM v2);
DROP TABLE t1, t2;
DROP VIEW v1, v2;
+set optimizer_switch=@save_derived_optimizer_switch;
diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test
index e35aca9b718..b674350af0a 100644
--- a/mysql-test/t/derived_view.test
+++ b/mysql-test/t/derived_view.test
@@ -4,9 +4,11 @@ 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);
@@ -925,6 +927,8 @@ 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
@@ -942,6 +946,7 @@ SELECT * FROM t3
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;
@@ -1031,6 +1036,7 @@ 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');
@@ -1071,6 +1077,9 @@ 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
@@ -1105,6 +1114,8 @@ 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 #
@@ -1119,6 +1130,9 @@ 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;
@@ -1137,6 +1151,8 @@ SELECT * FROM t3
SET SESSION join_cache_level = default;
+SET optimizer_switch=@save_optimizer_switch;
+
DROP VIEW v2;
DROP TABLE t1,t2,t3;
@@ -1263,3 +1279,4 @@ drop table t1,t2,t3;
# 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 a7eefad5ca5..051499f465b 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.
diff --git a/mysql-test/t/endspace.test b/mysql-test/t/endspace.test
index 7c71b05f687..69b8133c5f7 100644
--- a/mysql-test/t/endspace.test
+++ b/mysql-test/t/endspace.test
@@ -93,7 +93,9 @@ alter table t1 modify text1 text not null, pack_keys=1;
select * from t1 where text1 like 'teststring_%';
# The following gives wrong result in InnoDB
+--sorted_result
select text1, length(text1) from t1 where text1='teststring' or text1 like 'teststring_%';
+--sorted_result
select text1, length(text1) from t1 where text1='teststring' or text1 >= 'teststring\t';
select concat('|', text1, '|') from t1 order by text1;
drop table t1;
diff --git a/mysql-test/t/error_simulation.test b/mysql-test/t/error_simulation.test
index d4de4a9502d..c9f445c0cb0 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_dbug= '+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,9 +90,25 @@ SELECT * FROM t1 LEFT JOIN t2 ON ( t2.a < 10 OR t2.b < 10 );
SET SESSION debug_dbug= DEFAULT;
+SET optimizer_switch=@save_optimizer_switch;
+
DROP TABLE t1, t2;
--echo #
+--echo # Bug#11747970 34660: CRASH WHEN FEDERATED TABLE LOSES CONNECTION DURING INSERT ... SELECT
+--echo #
+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_dbug="+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_dbug = DEFAULT;
+DROP TABLE t1,t2;
+
+
+--echo #
--echo # End of 5.1 tests
--echo #
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index ece2e968b83..9b9e65d7b51 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -157,10 +157,11 @@ 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 );
@@ -178,6 +179,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 +189,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 #
@@ -248,12 +252,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))';
@@ -264,7 +268,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))';
@@ -306,7 +310,10 @@ 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/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 a18ce6b5c51..54535470d4c 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;
#
@@ -1250,12 +1253,15 @@ 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 #
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_str.test b/mysql-test/t/func_str.test
index bb22366a98d..8d01b84e359 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;
diff --git a/mysql-test/t/gis-precise.test b/mysql-test/t/gis-precise.test
index 1de8726a7bc..b48da25c3c9 100644
--- a/mysql-test/t/gis-precise.test
+++ b/mysql-test/t/gis-precise.test
@@ -78,6 +78,7 @@ select astext(ST_symdifference(geomfromtext('polygon((0 0, 1 0, 0 1, 0 0))'), ge
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))'));
@@ -87,6 +88,7 @@ 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
@@ -133,6 +135,7 @@ SELECT ASTEXT(ST_INTERSECTION(
#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))'),
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index 202e4f88cd8..f1e85ac0e40 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -753,57 +753,14 @@ drop table t1;
--echo # on char > 31 bytes".
--echo #
create table t1(a char(32) not null) engine=myisam;
---error ER_SPATIAL_MUST_HAVE_GEOM_COL
+--replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/
+--error ER_WRONG_ARGUMENTS
create spatial index i on t1 (a);
drop table t1;
--echo End of 5.1 tests
-#
-# Bug #50574 5.5.x allows spatial indexes on non-spatial
-# columns, causing crashes!
-#
---error ER_SPATIAL_MUST_HAVE_GEOM_COL
-CREATE TABLE t1(
- col0 BINARY NOT NULL,
- col2 TIMESTAMP,
- SPATIAL INDEX i1 (col0)
-) ENGINE=MyISAM;
-
-# Test other ways to add indices
-CREATE TABLE t1 (
- col0 BINARY NOT NULL,
- col2 TIMESTAMP
-) ENGINE=MyISAM;
-
---error ER_SPATIAL_MUST_HAVE_GEOM_COL
-CREATE SPATIAL INDEX idx0 ON t1(col0);
-
---error ER_SPATIAL_MUST_HAVE_GEOM_COL
-ALTER TABLE t1 ADD SPATIAL INDEX i1 (col0);
-
-CREATE TABLE t2 (
- col0 INTEGER NOT NULL,
- col1 POINT,
- col2 POINT
-);
-
---error ER_WRONG_ARGUMENTS
-CREATE SPATIAL INDEX idx0 ON t2 (col1, col2);
-
---error ER_WRONG_ARGUMENTS
-CREATE TABLE t3 (
- col0 INTEGER NOT NULL,
- col1 POINT,
- col2 LINESTRING,
- SPATIAL INDEX i1 (col1, col2)
-);
-
-# cleanup
-DROP TABLE t1;
-DROP TABLE t2;
-
#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))'));
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 30f5657ffdf..9e9df515bd2 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -339,8 +339,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;
#
@@ -1032,16 +1035,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;
DROP TABLE t1, t2;
diff --git a/mysql-test/t/group_min_max.test b/mysql-test/t/group_min_max.test
index 9258207050e..b984acc78ea 100644
--- a/mysql-test/t/group_min_max.test
+++ b/mysql-test/t/group_min_max.test
@@ -428,6 +428,8 @@ 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
@@ -439,6 +441,7 @@ 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
@@ -449,6 +452,8 @@ 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
@@ -460,6 +465,7 @@ 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
@@ -1149,6 +1155,43 @@ ORDER BY min_a;
DROP TABLE t1;
+--echo #
+--echo # LP BUG#888456 Wrong result with DISTINCT , ANY , subquery_cache=off , NOT NULL
+--echo #
+
+CREATE TABLE t1 ( a int NOT NULL) ;
+INSERT INTO t1 VALUES (28),(29),(9);
+
+CREATE TABLE t2 ( a int, KEY (a)) ;
+INSERT INTO t2 VALUES (1),(1),(1),(4),(4),(5),(5),(8),(8),(9);
+
+explain select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
+select (select t2.a from t2 where t2.a >= t1.a group by t2.a) from t1;
+
+drop table t1, t2;
+
+--echo #
+--echo # LP BUG#900375 Wrong result with derived_merge=ON, DISTINCT or GROUP BY, EXISTS
+--echo #
+
+CREATE TABLE t1 ( a INT, b INT, KEY (b) );
+INSERT INTO t1 VALUES
+(100,10),(101,11),(102,12),(103,13),(104,14),
+(105,15),(106,16),(107,17),(108,18),(109,19);
+
+EXPLAIN
+SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
+WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
+SELECT alias1.* FROM t1, (SELECT * FROM t1) AS alias1
+WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
+
+EXPLAIN
+SELECT alias1.* FROM t1, t1 AS alias1
+WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
+SELECT alias1.* FROM t1, t1 AS alias1
+WHERE EXISTS ( SELECT DISTINCT b FROM t1 WHERE b <= alias1.a ) ;
+
+drop table t1;
--echo End of 5.1 tests
diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test
index e2aa5f45a2b..bab46e00136 100644
--- a/mysql-test/t/index_merge_innodb.test
+++ b/mysql-test/t/index_merge_innodb.test
@@ -67,6 +67,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.
@@ -88,6 +90,7 @@ 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
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 5b5e2137d0e..2e8b1420db8 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -965,6 +965,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,
@@ -973,6 +975,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 036dd944cc3..7c2bd44f31f 100644
--- a/mysql-test/t/information_schema_all_engines.test
+++ b/mysql-test/t/information_schema_all_engines.test
@@ -8,6 +8,8 @@
--source include/not_staging.inc
use INFORMATION_SCHEMA;
+--replace_result Tables_in_INFORMATION_SCHEMA Tables_in_information_schema
+--sorted_result
show tables;
#
@@ -27,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;
SELECT t.table_name, c1.column_name
FROM information_schema.tables t
INNER JOIN
@@ -41,7 +43,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
@@ -69,8 +71,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/join.test b/mysql-test/t/join.test
index 82e67904e9f..bfe5f085e93 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
#
@@ -1025,3 +1028,4 @@ 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;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test
index caf5af57df7..4600da9ee17 100644
--- a/mysql-test/t/join_cache.test
+++ b/mysql-test/t/join_cache.test
@@ -33,6 +33,8 @@ SELECT COUNT(*) FROM CountryLanguage;
show variables like 'join_buffer_size';
+set join_cache_level=1;
+
show variables like 'join_cache_level';
EXPLAIN
@@ -196,7 +198,7 @@ SELECT Country.Name, Country.Population, City.Name, City.Population
DROP INDEX City_Population ON City;
DROP INDEX City_Name ON City;
-set join_cache_level=default;
+set join_cache_level=1;
set join_buffer_size=256;
show variables like 'join_buffer_size';
@@ -2191,6 +2193,8 @@ 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;
@@ -2577,11 +2581,6 @@ INSERT INTO t2 VALUES
(1, 12, 102), (8, 81, 801), (7, 70, 700), (12, 120, 1200),
(8, 82, 802), (1, 13, 103), (1, 14, 104), (3, 31, 301),
(1, 15, 105), (8, 83, 803), (7, 71, 701);
-INSERT INTO t2 VALUES
- (108, 80, 800), (101, 10, 100), (101, 11, 101), (103, 30, 300),
- (101, 12, 102), (108, 81, 801), (107, 70, 700), (1012, 120, 1200),
- (108, 82, 802), (101, 13, 103), (101, 14, 104), (103, 31, 301),
- (101, 15, 105), (108, 83, 803), (107, 71, 701);
SET SESSION join_cache_level = 4;
SET SESSION join_buffer_size = 256;
@@ -3254,5 +3253,175 @@ 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;
+
# 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 b617331de38..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);
@@ -1271,5 +1283,7 @@ SELECT * FROM t1 LEFT JOIN
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
index 809755b1fbf..0e8646bceda 100644
--- a/mysql-test/t/join_nested_jcl6.test
+++ b/mysql-test/t/join_nested_jcl6.test
@@ -11,6 +11,9 @@ 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
#
@@ -104,3 +107,5 @@ 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 059606d9f86..82096001b75 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,
@@ -1474,3 +1485,5 @@ DEALLOCATE PREPARE stmt;
SET SESSION join_cache_level=default;
DROP TABLE t1,t2,t3;
+
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/join_outer_jcl6.test b/mysql-test/t/join_outer_jcl6.test
index 025e44493af..e34cc615216 100644
--- a/mysql-test/t/join_outer_jcl6.test
+++ b/mysql-test/t/join_outer_jcl6.test
@@ -11,9 +11,14 @@ 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/maria_mrr.test b/mysql-test/t/maria_mrr.test
index d67572033c8..6c6a8c4e7b6 100644
--- a/mysql-test/t/maria_mrr.test
+++ b/mysql-test/t/maria_mrr.test
@@ -78,6 +78,9 @@ 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
@@ -90,6 +93,8 @@ 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 #
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index fa82be90427..9bdd6faa422 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1700,6 +1700,24 @@ DROP TABLE t1;
SET myisam_sort_buffer_size=@@global.myisam_sort_buffer_size;
SET myisam_repair_threads=@@global.myisam_repair_threads;
+--echo #
+--echo # BUG#11757032 - 49030: OPTIMIZE TABLE BREAKS MYISAM TABLE WHEN
+--echo # USING MYISAM_USE_MMAP ON WINDOWS
+--echo #
+SET GLOBAL myisam_use_mmap=1;
+CREATE TABLE t1(a INT);
+INSERT INTO t1 VALUES(1),(2);
+DELETE FROM t1 WHERE a=1;
+FLUSH TABLE t1;
+LOCK TABLE t1 WRITE;
+OPTIMIZE TABLE t1;
+INSERT INTO t1 VALUES(3);
+UNLOCK TABLES;
+SELECT * FROM t1;
+CHECK TABLE t1;
+DROP TABLE t1;
+SET GLOBAL myisam_use_mmap=default;
+
--echo End of 5.1 tests
--echo #
diff --git a/mysql-test/t/myisam_icp.test b/mysql-test/t/myisam_icp.test
index bbff6c30e56..0e306a850c5 100644
--- a/mysql-test/t/myisam_icp.test
+++ b/mysql-test/t/myisam_icp.test
@@ -245,6 +245,9 @@ 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
@@ -255,6 +258,8 @@ 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;
set optimizer_switch=@myisam_icp_tmp;
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index d514ae88afd..82116558717 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -157,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)
@@ -179,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;
#
diff --git a/mysql-test/t/parser_stack.test b/mysql-test/t/parser_stack.test
index bdcad5aa1b4..8bc316da18e 100644
--- a/mysql-test/t/parser_stack.test
+++ b/mysql-test/t/parser_stack.test
@@ -1,18 +1,3 @@
-# Copyright (C) 2008 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
-
#
# These tests are designed to cause an internal parser stack overflow,
# and trigger my_yyoverflow().
diff --git a/mysql-test/t/partition_innodb_plugin.test b/mysql-test/t/partition_innodb_plugin.test
index d2a010335f2..9da22d55ef7 100644
--- a/mysql-test/t/partition_innodb_plugin.test
+++ b/mysql-test/t/partition_innodb_plugin.test
@@ -3,6 +3,32 @@
let $MYSQLD_DATADIR= `SELECT @@datadir`;
+--echo #
+--echo # Bug#11766879/Bug#60106: DIFF BETWEEN # OF INDEXES IN MYSQL VS INNODB,
+--echo # PARTITONING, ON INDEX CREATE
+--echo #
+call mtr.add_suppression("contains 2 indexes inside InnoDB, which is different from the number of indexes 1 defined in the MySQL");
+CREATE TABLE t1 (
+ id bigint NOT NULL AUTO_INCREMENT,
+ time date,
+ id2 bigint not null,
+ PRIMARY KEY (id,time)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8
+/*!50100 PARTITION BY RANGE(TO_DAYS(time))
+(PARTITION p10 VALUES LESS THAN (734708) ENGINE = InnoDB,
+ PARTITION p20 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) */;
+
+INSERT INTO t1 (time,id2) VALUES ('2011-07-24',1);
+INSERT INTO t1 (time,id2) VALUES ('2011-07-25',1);
+INSERT INTO t1 (time,id2) VALUES ('2011-07-25',1);
+
+--error ER_DUP_ENTRY
+CREATE UNIQUE INDEX uk_time_id2 on t1(time,id2);
+
+SELECT COUNT(*) FROM t1;
+
+DROP TABLE t1;
+
call mtr.add_suppression("InnoDB: Error: table `test`.`t1` .* InnoDB internal");
--echo #
--echo # Bug#55091: Server crashes on ADD PARTITION after a failed attempt
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 e660c017854..ce7c498133c 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -166,12 +166,18 @@ 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;
@@ -3091,10 +3097,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 #
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index aad02219215..e87e57702ac 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -771,7 +771,19 @@ show status like "Qcache_hits";
show status like "Qcache_queries_in_cache";
show status like "Qcache_inserts";
show status like "Qcache_hits";
+
+set query_cache_strip_comments=1;
+(select a from t1) union (select a from t1);
+(select a from t1) /* */union (select a from t1);
+set 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);
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 3781f7a5d43..2a8913730ca 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
@@ -4262,6 +4273,22 @@ SELECT t2.f23 FROM
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"
+#
+
+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;
+SELECT f1 FROM t1 GROUP BY '123' = 'abc';
+SELECT 1 FROM t1 GROUP BY 1;
+set sql_buffer_result=1;
+SELECT f1 FROM t1 GROUP BY 1;
+SELECT f1 FROM t1 GROUP BY '123' = 'abc';
+SELECT 1 FROM t1 GROUP BY 1;
+drop table t1;
--echo #
@@ -4390,3 +4417,17 @@ DROP TABLE t1;
--echo # End of test BUG#57203
+--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;
diff --git a/mysql-test/t/select_jcl6.test b/mysql-test/t/select_jcl6.test
index 295efa632db..f7c1aa988c7 100644
--- a/mysql-test/t/select_jcl6.test
+++ b/mysql-test/t/select_jcl6.test
@@ -11,9 +11,14 @@ 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/subselect.test b/mysql-test/t/subselect.test
index 3d7050ebc25..cb43eb9f646 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -15,7 +15,16 @@ 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 optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
+
+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);
@@ -94,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);
@@ -3235,6 +3247,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');
@@ -3256,6 +3272,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
@@ -3404,8 +3421,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 #
@@ -3486,39 +3506,39 @@ ORDER BY outr.pk;
DROP TABLE t1,t2;
-#--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 # 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 End of 5.0 tests.
@@ -4729,8 +4749,12 @@ 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;
@@ -4741,7 +4765,8 @@ DROP table t1,t2;
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 )
@@ -4750,7 +4775,7 @@ SELECT b FROM t1
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 #
@@ -4895,6 +4920,9 @@ 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
@@ -4904,12 +4932,12 @@ 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 End of 5.3 tests
---echo End of 5.5 tests.
-
--echo #
--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER
--echo #
@@ -4943,7 +4971,10 @@ CREATE TABLE t1 (a INT, b INT, INDEX (a));
INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20);
--echo
+set @tmp_optimizer_switch=@@optimizer_switch;
+set optimizer_switch='derived_merge=off,derived_with_keys=off';
EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t;
+set optimizer_switch=@tmp_optimizer_switch;
--echo
EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7);
@@ -5071,6 +5102,183 @@ 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;
+
+
+--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 5f819ed39ba..8d2939bdb53 100644
--- a/mysql-test/t/subselect2.test
+++ b/mysql-test/t/subselect2.test
@@ -172,5 +172,36 @@ SELECT t1.* FROM t1 WHERE (SELECT COUNT(*) FROM t3,t2 WHERE t3.c=t2.a
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;
+
set optimizer_switch=@subselect2_test_tmp;
diff --git a/mysql-test/t/subselect3.test b/mysql-test/t/subselect3.test
index 3800b019462..0221315eb35 100644
--- a/mysql-test/t/subselect3.test
+++ b/mysql-test/t/subselect3.test
@@ -4,6 +4,14 @@ 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';
+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
@@ -925,8 +933,11 @@ 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
diff --git a/mysql-test/t/subselect3_jcl6.test b/mysql-test/t/subselect3_jcl6.test
index 8d880809476..e4b1c144b93 100644
--- a/mysql-test/t/subselect3_jcl6.test
+++ b/mysql-test/t/subselect3_jcl6.test
@@ -11,9 +11,12 @@ 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 a5a4e0a3cfe..db4f1635999 100644
--- a/mysql-test/t/subselect4.test
+++ b/mysql-test/t/subselect4.test
@@ -528,6 +528,27 @@ SELECT * FROM t1
WHERE f3 = (
SELECT f3 FROM t1
WHERE ( f10, f10 ) IN ( SELECT f11, f11 FROM t2 GROUP BY f11 ));
+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;
@@ -856,18 +877,27 @@ 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 #
@@ -943,7 +973,7 @@ EXPLAIN
SELECT * FROM t1 WHERE
(SELECT f2 FROM t2
WHERE f4 <= ALL
- (SELECT SQ1_t1.f4
+ (SELECT max(SQ1_t1.f4)
FROM t3 AS SQ1_t1 JOIN t3 AS SQ1_t3 ON SQ1_t3.f4
GROUP BY SQ1_t1.f4));
@@ -1162,47 +1192,49 @@ INSERT INTO t2 VALUES
(10,5,'d1d');
set @save_optimizer_switch=@@optimizer_switch;
-set @@optimizer_switch = 'materialization=off';
+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 f2 , f1 FROM t0 GROUP BY f2 , f1 );
+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 f2 , f1 FROM t0 GROUP BY f2 , f1 );
+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 f1a, f2a FROM t1 GROUP BY f1a, f2a);
-SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT 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);
+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 f1a FROM t1 GROUP BY f1a, f2a);
-SELECT * FROM t2 WHERE (f1b) IN (SELECT f1a FROM t1 GROUP BY f1a, f2a);
+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 = 'materialization=on';
+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 f2 , f1 FROM t0 GROUP BY f2 , f1 );
+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 f2 , f1 FROM t0 GROUP BY f2 , f1 );
+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 f1a, f2a FROM t1 GROUP BY f1a, f2a);
-SELECT * FROM t2 WHERE (f1b, f2b) IN (SELECT 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);
+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 f1a FROM t1 GROUP BY f1a, f2a);
-SELECT * FROM t2 WHERE (f1b) IN (SELECT f1a FROM t1 GROUP BY f1a, f2a);
+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;
diff --git a/mysql-test/t/subselect_cache.test b/mysql-test/t/subselect_cache.test
index d06bf06756a..6a104144302 100644
--- a/mysql-test/t/subselect_cache.test
+++ b/mysql-test/t/subselect_cache.test
@@ -3,6 +3,10 @@ drop table if exists t0,t1,t2,t3,t4,t5,t6,t7,t8,t9;
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);
@@ -1558,6 +1562,7 @@ 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
+--disable_warnings
SELECT table1 .`col_varchar_nokey`
FROM t2 table1 RIGHT JOIN t1 LEFT JOIN (
SELECT SUBQUERY1_t2 .*
@@ -1567,6 +1572,7 @@ FROM t1 ) table4 JOIN ( t1 table5 JOIN t2 table6 ON table5 .`pk` ) ON table5 .`c
WHERE table3 .`col_varchar_key` IN (
SELECT `col_varchar_key`
FROM t2 ) AND table1 .`col_varchar_key` OR table1 .`pk` ;
+--enable_warnings
drop table t1,t2;
set @@optimizer_switch= default;
@@ -1696,5 +1702,7 @@ 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_mat_cost_bugs.test b/mysql-test/t/subselect_mat_cost_bugs.test
index 4ce19012e0c..8205e94b203 100644
--- a/mysql-test/t/subselect_mat_cost_bugs.test
+++ b/mysql-test/t/subselect_mat_cost_bugs.test
@@ -167,8 +167,8 @@ CREATE TABLE t3 ( f2 varchar(1)) ;
EXPLAIN SELECT f2 FROM t3 WHERE (
SELECT MAX( pk ) FROM t1
WHERE EXISTS (
- SELECT DISTINCT f1
- FROM t2
+ SELECT max(f1)
+ FROM t2 GROUP BY f1
)
) IS NULL ;
@@ -183,6 +183,9 @@ 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);
@@ -192,6 +195,7 @@ 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 #
@@ -204,6 +208,9 @@ 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
@@ -223,6 +230,7 @@ WHERE (
)
ORDER BY field1 ;
+set optimizer_switch=@tmp_optimizer_switch;
drop table t1,t2;
--echo #
diff --git a/mysql-test/t/subselect_no_mat.test b/mysql-test/t/subselect_no_mat.test
index 0265ec91e88..ccd93af64ce 100644
--- a/mysql-test/t/subselect_no_mat.test
+++ b/mysql-test/t/subselect_no_mat.test
@@ -5,8 +5,13 @@ 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
index 724cbab6310..8a699fefaf7 100644
--- a/mysql-test/t/subselect_no_opts.test
+++ b/mysql-test/t/subselect_no_opts.test
@@ -4,6 +4,10 @@
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
index fe8ff749a59..a8ff559b82b 100644
--- a/mysql-test/t/subselect_no_scache.test
+++ b/mysql-test/t/subselect_no_scache.test
@@ -4,8 +4,12 @@
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
index c836c12ec50..46791667173 100644
--- a/mysql-test/t/subselect_no_semijoin.test
+++ b/mysql-test/t/subselect_no_semijoin.test
@@ -3,6 +3,10 @@
#
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_partial_match.test b/mysql-test/t/subselect_partial_match.test
index be78360c76b..fd1e6de716c 100644
--- a/mysql-test/t/subselect_partial_match.test
+++ b/mysql-test/t/subselect_partial_match.test
@@ -622,8 +622,11 @@ 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;
@@ -775,4 +778,26 @@ 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
index 5ae968742aa..f34cf5ba338 100644
--- a/mysql-test/t/subselect_sj.test
+++ b/mysql-test/t/subselect_sj.test
@@ -10,6 +10,17 @@ 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');
+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;
@@ -1690,6 +1701,9 @@ INSERT INTO t2 VALUES (1,2,4,'22:34:09','v','v'),
(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,
@@ -1720,6 +1734,8 @@ WHERE
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;
@@ -1761,52 +1777,43 @@ 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 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 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 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 t5 ( f2 int) ;
-CREATE TABLE t6 ( f4 varchar(3));
-INSERT INTO t6 VALUES ('RUS'),('USA');
+#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
-SELECT *
-FROM t1
-WHERE ( 1 , 3 ) IN (
- SELECT t2.f1 , MAX( t3.f3 )
- FROM t2
- JOIN t3
- WHERE t3.f4 IN (
- SELECT t4.f5
- FROM t4
- STRAIGHT_JOIN t5
- WHERE t4.f4 < t2.f5
- )
-) AND ( 'p' , 'k' ) IN (
- SELECT f4 , f4 FROM t6
-);
+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,t2,t3,t4,t5,t6;
+drop table t1;
--echo #
--echo # BUG#877288: Wrong result with semijoin + materialization + multipart key
@@ -1910,5 +1917,105 @@ 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;
+
# The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp;
diff --git a/mysql-test/t/subselect_sj2.test b/mysql-test/t/subselect_sj2.test
index 0fd8cab1a04..a77a70bbe4e 100644
--- a/mysql-test/t/subselect_sj2.test
+++ b/mysql-test/t/subselect_sj2.test
@@ -6,8 +6,19 @@
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;
+drop table if exists t0, t1, t2, t3, t4, t5;
drop view if exists v1;
--enable_warnings
@@ -46,7 +57,6 @@ create table t3 (
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);
@@ -74,7 +84,7 @@ from t0 A, t0 B where B.a <5;
# because it does not hold when this file is included
# into subselect_sj2_jcl6.test)
#
---replace_regex /Using join buffer//
+#--replace_regex /Using join buffer//
explain select * from t3 where b in (select a from t0);
select * from t3 where b in (select A.a+B.a from t0 A, t0 B where B.a<5);
diff --git a/mysql-test/t/subselect_sj2_jcl6.test b/mysql-test/t/subselect_sj2_jcl6.test
index e4ae249c711..fbc474f7067 100644
--- a/mysql-test/t/subselect_sj2_jcl6.test
+++ b/mysql-test/t/subselect_sj2_jcl6.test
@@ -11,10 +11,103 @@ 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
index fdfa0f311d3..7c3b37b517a 100644
--- a/mysql-test/t/subselect_sj2_mat.test
+++ b/mysql-test/t/subselect_sj2_mat.test
@@ -8,3 +8,32 @@ set optimizer_switch='mrr=on,mrr_sort_keys=on,index_condition_pushdown=on';
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;
+
+
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
index fc539ec1a01..4eeaa465b11 100644
--- a/mysql-test/t/subselect_sj_jcl6.test
+++ b/mysql-test/t/subselect_sj_jcl6.test
@@ -13,6 +13,9 @@ 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 #
@@ -91,3 +94,5 @@ 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
index a72128bf5ed..2a5b0f56877 100644
--- a/mysql-test/t/subselect_sj_mat.test
+++ b/mysql-test/t/subselect_sj_mat.test
@@ -7,6 +7,8 @@ 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;
@@ -86,8 +88,8 @@ 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 b1 from t2i where b1 > '0' group by b1);
-select * from t1i where a1 in (select b1 from t2i where b1 > '0' group by b1);
+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$//
@@ -97,8 +99,8 @@ 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, b2 from t2i where b1 > '0' group by b1, b2);
-select * from t1i where (a1, a2) in (select b1, b2 from t2i where b1 > '0' group by b1, b2);
+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
@@ -833,14 +835,14 @@ create table t2 (b1 int);
insert into t1 values (5);
# Query with group by, executed via materialization
-explain select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
-select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+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 b1 from t2 group by b1);
-select min(a1) from t1 where 7 in (select b1 from t2 group by b1);
+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;
@@ -898,7 +900,7 @@ WHERE (t1i) IN (
SELECT t2i
FROM t2
WHERE (t2i) IN (
- SELECT t3i
+ SELECT max(t3i)
FROM t3
GROUP BY t3i
)
@@ -1022,12 +1024,15 @@ 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;
@@ -1424,8 +1429,88 @@ ON ( t2.f5 ) IN (
);
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 # 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
index 4f50b4cbc4d..e47e72ffe97 100644
--- a/mysql-test/t/subselect_sj_nonmerged.test
+++ b/mysql-test/t/subselect_sj_nonmerged.test
@@ -55,13 +55,19 @@ 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
diff --git a/mysql-test/t/table_elim.test b/mysql-test/t/table_elim.test
index 3b584ce2b38..dc32618eb8c 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;
@@ -518,3 +521,4 @@ EXPLAIN SELECT alias1.* FROM t3 LEFT JOIN v1 as alias1 ON ( t3.a = alias1.b );
drop view v1;
DROP TABLE t1,t2,t3;
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index 1bd637f477c..ea4ede6da41 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -2571,3 +2571,43 @@ DROP TABLE t1;
--echo
--echo End of 5.5 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/type_datetime.test b/mysql-test/t/type_datetime.test
index 46c0d2d56d5..989e0d29210 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -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;
diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test
index 4f4b1962cc3..bf7e3794a19 100644
--- a/mysql-test/t/type_newdecimal.test
+++ b/mysql-test/t/type_newdecimal.test
@@ -1244,6 +1244,27 @@ show create table t1;
select * from t1;
DROP TABLE t1;
+--echo #
+--echo # Bug#12563865
+--echo # ROUNDED,TMP_BUF,DECIMAL_VALUE STACK CORRUPTION IN ALL VERSIONS >=5.0
+--echo #
+
+let $nine_81=
+999999999999999999999999999999999999999999999999999999999999999999999999999999999;
+
+eval SELECT substring(('M') FROM ($nine_81)) AS foo;
+eval SELECT min($nine_81) AS foo;
+eval SELECT multipolygonfromtext(('4294967294.1'),($nine_81)) AS foo;
+eval SELECT convert(($nine_81), decimal(30,30)) AS foo;
+eval SELECT bit_xor($nine_81) AS foo;
+eval SELECT -($nine_81) AS foo;
+eval SELECT date_sub(($nine_81),
+ interval ((SELECT date_add((0x77500000),
+ interval ('Oml') second)))
+ day_minute)
+AS foo;
+eval SELECT truncate($nine_81, 28) AS foo;
+
--echo End of 5.0 tests
#
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index c9bc3f5e1aa..9c03f93028c 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/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;
#
@@ -1094,6 +1097,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/variables-notembedded.test b/mysql-test/t/variables-notembedded.test
index b440cfa47b0..471212bf38f 100644
--- a/mysql-test/t/variables-notembedded.test
+++ b/mysql-test/t/variables-notembedded.test
@@ -123,7 +123,12 @@ CONNECT (con1,localhost,root,,test);
SHOW SESSION VARIABLES LIKE 'max_allowed_packet';
SHOW SESSION VARIABLES LIKE 'net_buffer_length';
--disable_query_log
---error ER_NET_PACKET_TOO_LARGE
+#Sending a packet that is too big can result in either
+#ER_NET_PACKET_TOO_LARGE or a socket error on the client side (2013= CR_SERVER_LOST)
+#The server does not make any attempts to gracefully close client connection and ensuring
+#client fully read the last packet. Server just closes the socket after it has send.
+#Client thus can get either a socket error, or EOF, or an error packet with ER_NET_PACKET_TOO_LARGE
+--error ER_NET_PACKET_TOO_LARGE,2013
INSERT INTO t1 VALUES ('123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890');
--enable_query_log
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index df47526ef21..5fd8da745e4 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -9,6 +9,9 @@ use test;
# Save the initial number of concurrent sessions.
--source include/count_sessions.inc
+SET @save_optimizer_switch=@@optimizer_switch;
+SET optimizer_switch='outer_join_with_cache=off';
+
#
# some basic test of views and its functionality
#
@@ -4489,3 +4492,5 @@ SELECT * FROM t1 RIGHT JOIN v2 ON ( v2.a = t1.a ) WHERE v2.b IN ( SELECT b FROM
DROP VIEW v2;
DROP TABLE t1, t2, t3;
+
+SET optimizer_switch=@save_optimizer_switch;
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 5896e25feda..1b9c2c0a25e 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -127,21 +127,26 @@ create view mysqltest.v1 (c,d) as select a+1,b+1 from mysqltest.t1;
create algorithm=temptable view mysqltest.v2 (c,d) as select a+1,b+1 from mysqltest.t1;
create view mysqltest.v3 (c,d) as select a+1,b+1 from mysqltest.t2;
create algorithm=temptable view mysqltest.v4 (c,d) as select a+1,b+1 from mysqltest.t2;
+# v5: SHOW VIEW, but no SELECT
+create view mysqltest.v5 (c,d) as select a+1,b+1 from mysqltest.t1;
grant select on mysqltest.v1 to mysqltest_1@localhost;
grant select on mysqltest.v2 to mysqltest_1@localhost;
grant select on mysqltest.v3 to mysqltest_1@localhost;
grant select on mysqltest.v4 to mysqltest_1@localhost;
+grant show view on mysqltest.v5 to mysqltest_1@localhost;
connection user1;
-# all selects works
+# all SELECTs works, except v5 which lacks SELECT privs
select c from mysqltest.v1;
select c from mysqltest.v2;
select c from mysqltest.v3;
select c from mysqltest.v4;
+--error ER_TABLEACCESS_DENIED_ERROR
+select c from mysqltest.v5;
# test of show coluns
show columns from mysqltest.v1;
show columns from mysqltest.v2;
-# but explain/show do not
+# explain/show fail
--error ER_VIEW_NO_EXPLAIN
explain select c from mysqltest.v1;
--error ER_TABLEACCESS_DENIED_ERROR
@@ -158,15 +163,26 @@ show create view mysqltest.v3;
explain select c from mysqltest.v4;
--error ER_TABLEACCESS_DENIED_ERROR
show create view mysqltest.v4;
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select c from mysqltest.v5;
+show create view mysqltest.v5;
+# missing SELECT on underlying t1, no SHOW VIEW on v1 either.
+--error ER_VIEW_NO_EXPLAIN
+explain select c from mysqltest.v1;
+# missing SHOW VIEW
+--error ER_TABLEACCESS_DENIED_ERROR
+show create view mysqltest.v1;
# allow to see one of underlying table
connection root;
+grant show view on mysqltest.v1 to mysqltest_1@localhost;
grant select on mysqltest.t1 to mysqltest_1@localhost;
connection user1;
-# EXPLAIN of view on above table works
+# EXPLAIN works
explain select c from mysqltest.v1;
---error ER_TABLEACCESS_DENIED_ERROR
show create view mysqltest.v1;
+# missing SHOW VIEW
+--error ER_VIEW_NO_EXPLAIN
explain select c from mysqltest.v2;
--error ER_TABLEACCESS_DENIED_ERROR
show create view mysqltest.v2;
@@ -179,6 +195,11 @@ show create view mysqltest.v3;
explain select c from mysqltest.v4;
--error ER_TABLEACCESS_DENIED_ERROR
show create view mysqltest.v4;
+# we have SHOW VIEW on v5, and SELECT on t1 -- not enough
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select c from mysqltest.v5;
+# we can SHOW CREATE VIEW though
+show create view mysqltest.v5;
# allow to see any view in mysqltest database
connection root;
@@ -188,8 +209,12 @@ explain select c from mysqltest.v1;
show create view mysqltest.v1;
explain select c from mysqltest.v2;
show create view mysqltest.v2;
+# have SHOW VIEW | SELECT on v3, but no SELECT on t2
+--error ER_VIEW_NO_EXPLAIN
explain select c from mysqltest.v3;
show create view mysqltest.v3;
+# have SHOW VIEW | SELECT on v4, but no SELECT on t2
+--error ER_VIEW_NO_EXPLAIN
explain select c from mysqltest.v4;
show create view mysqltest.v4;
@@ -1237,6 +1262,334 @@ DROP VIEW db1.v1;
DROP TABLE db1.t1;
DROP DATABASE db1;
+connection default;
+
+
+--echo Bug #11765687/#58677:
+--echo No privilege on table/view, but can know #rows / underlying table's name
+
+# As a root-like user
+connect (root,localhost,root,,test);
+connection root;
+
+create database mysqltest1;
+create table mysqltest1.t1 (i int);
+create table mysqltest1.t2 (j int);
+create table mysqltest1.t3 (k int, secret int);
+
+create user alice@localhost;
+create user bob@localhost;
+create user cecil@localhost;
+create user dan@localhost;
+create user eugene@localhost;
+create user fiona@localhost;
+create user greg@localhost;
+create user han@localhost;
+create user inga@localhost;
+create user jamie@localhost;
+create user karl@localhost;
+create user lena@localhost;
+create user mhairi@localhost;
+create user noam@localhost;
+create user olga@localhost;
+create user pjotr@localhost;
+create user quintessa@localhost;
+
+grant all privileges on mysqltest1.* to alice@localhost with grant option;
+
+#
+--echo ... as alice
+connect (test11765687,localhost,alice,,mysqltest1);
+connection test11765687;
+
+create view v1 as select * from t1;
+create view v2 as select * from v1, t2;
+create view v3 as select k from t3;
+
+grant select on mysqltest1.v1 to bob@localhost;
+
+grant show view on mysqltest1.v1 to cecil@localhost;
+
+grant select, show view on mysqltest1.v1 to dan@localhost;
+grant select on mysqltest1.t1 to dan@localhost;
+
+grant select on mysqltest1.* to eugene@localhost;
+
+grant select, show view on mysqltest1.v2 to fiona@localhost;
+
+grant select, show view on mysqltest1.v2 to greg@localhost;
+grant show view on mysqltest1.v1 to greg@localhost;
+
+grant select(k) on mysqltest1.t3 to han@localhost;
+grant select, show view on mysqltest1.v3 to han@localhost;
+
+grant select on mysqltest1.t1 to inga@localhost;
+grant select on mysqltest1.t2 to inga@localhost;
+grant select on mysqltest1.v1 to inga@localhost;
+grant select, show view on mysqltest1.v2 to inga@localhost;
+
+grant select on mysqltest1.t1 to jamie@localhost;
+grant select on mysqltest1.t2 to jamie@localhost;
+grant show view on mysqltest1.v1 to jamie@localhost;
+grant select, show view on mysqltest1.v2 to jamie@localhost;
+
+grant select on mysqltest1.t1 to karl@localhost;
+grant select on mysqltest1.t2 to karl@localhost;
+grant select, show view on mysqltest1.v1 to karl@localhost;
+grant select on mysqltest1.v2 to karl@localhost;
+
+grant select on mysqltest1.t1 to lena@localhost;
+grant select on mysqltest1.t2 to lena@localhost;
+grant select, show view on mysqltest1.v1 to lena@localhost;
+grant show view on mysqltest1.v2 to lena@localhost;
+
+grant select on mysqltest1.t1 to mhairi@localhost;
+grant select on mysqltest1.t2 to mhairi@localhost;
+grant select, show view on mysqltest1.v1 to mhairi@localhost;
+grant select, show view on mysqltest1.v2 to mhairi@localhost;
+
+grant select on mysqltest1.t1 to noam@localhost;
+grant select, show view on mysqltest1.v1 to noam@localhost;
+grant select, show view on mysqltest1.v2 to noam@localhost;
+
+grant select on mysqltest1.t2 to olga@localhost;
+grant select, show view on mysqltest1.v1 to olga@localhost;
+grant select, show view on mysqltest1.v2 to olga@localhost;
+
+grant select on mysqltest1.t1 to pjotr@localhost;
+grant select on mysqltest1.t2 to pjotr@localhost;
+grant select, show view on mysqltest1.v2 to pjotr@localhost;
+
+grant select, show view on mysqltest1.v1 to quintessa@localhost;
+
+disconnect test11765687;
+
+#
+--echo ... as bob
+connect (test11765687,localhost,bob,,mysqltest1);
+connection test11765687;
+
+select * from v1; # Should succeed.
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v1; # fail, no SHOW_VIEW
+
+disconnect test11765687;
+
+#
+--echo ... as cecil
+connect (test11765687,localhost,cecil,,mysqltest1);
+connection test11765687;
+
+--error ER_TABLEACCESS_DENIED_ERROR
+select * from v1; # fail, no SELECT
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from v1; # fail, no SELECT
+
+disconnect test11765687;
+
+#
+--echo ... as dan
+connect (test11765687,localhost,dan,,mysqltest1);
+connection test11765687;
+
+select * from v1; # Should succeed.
+explain select * from v1; # Should succeed.
+
+disconnect test11765687;
+
+#
+--echo ... as eugene
+connect (test11765687,localhost,eugene,,mysqltest1);
+connection test11765687;
+
+select * from v1; # Should succeed.
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v1; # fail, no SHOW_VIEW
+
+disconnect test11765687;
+
+#
+--echo ... as fiona
+connect (test11765687,localhost,fiona,,mysqltest1);
+connection test11765687;
+
+select * from v2; # Should succeed.
+show create view v2; # Should succeed, but...
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from t1; # fail, shouldn't see t1!
+--error ER_TABLEACCESS_DENIED_ERROR
+# err msg must give view name, no table names!!
+explain select * from v1; # fail, have no privs on v1!
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from t2; # fail, have no privs on t2!
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2; # fail, shouldn't see t2!
+
+disconnect test11765687;
+
+#
+--echo ... as greg
+connect (test11765687,localhost,greg,,mysqltest1);
+connection test11765687;
+
+select * from v2; # Should succeed.
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from v1; # fail; no SELECT on v1!
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2; # fail; no SELECT on v1!
+
+disconnect test11765687;
+
+#
+--echo ... as han
+connect (test11765687,localhost,han,,mysqltest1);
+connection test11765687;
+
+--error ER_TABLEACCESS_DENIED_ERROR
+select * from t3; # don't have privs on all columns,
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from t3; # so EXPLAIN on "forbidden" columns should fail.
+select k from t3; # but we do have SELECT on column k though,
+explain select k from t3; # so EXPLAIN just on k should work,
+select * from v3; # and so should SELECT on view only using allowed columns
+explain select * from v3; # as should the associated EXPLAIN
+
+disconnect test11765687;
+
+#
+--echo ... as inga
+connect (test11765687,localhost,inga,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel on t1/t2, only sel v1
+# fail: lacks show on v1
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as jamie
+connect (test11765687,localhost,jamie,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel on t1/t2, only show v1
+# fail: lacks sel on v1
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as karl
+connect (test11765687,localhost,karl,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel only on v2, sel on t1/t2, sel/show v1
+# fail: lacks show on v2
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as lena
+
+connect (test11765687,localhost,lena,,mysqltest1);
+connection test11765687;
+--error ER_TABLEACCESS_DENIED_ERROR
+select * from v2;
+# has show only on v2, sel on t1/t2, sel/show v1
+# fail: lacks sel on v2
+--error ER_TABLEACCESS_DENIED_ERROR
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as mhairi
+connect (test11765687,localhost,mhairi,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel on t1/t2, sel/show v1
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as noam
+connect (test11765687,localhost,noam,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel only on t1, sel/show v1 (no sel on t2!)
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as olga
+connect (test11765687,localhost,olga,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel only on t2, sel/show v1 (no sel on t1!)
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as pjotr
+connect (test11765687,localhost,pjotr,,mysqltest1);
+connection test11765687;
+
+select * from v2;
+# has sel/show on v2, sel only on t2, nothing on v1
+# fail: lacks show on v1
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v2;
+disconnect test11765687;
+
+#
+--echo ... as quintessa
+connect (test11765687,localhost,quintessa,,mysqltest1);
+connection test11765687;
+
+select * from v1; # Should succeed.
+--error ER_VIEW_NO_EXPLAIN
+explain select * from v1; # fail: lacks select on t1
+
+disconnect test11765687;
+
+# cleanup
+
+#
+--echo ... as root again at last: clean-up time!
+connection root;
+
+drop user alice@localhost;
+drop user bob@localhost;
+drop user cecil@localhost;
+drop user dan@localhost;
+drop user eugene@localhost;
+drop user fiona@localhost;
+drop user greg@localhost;
+drop user han@localhost;
+drop user inga@localhost;
+drop user jamie@localhost;
+drop user karl@localhost;
+drop user lena@localhost;
+drop user mhairi@localhost;
+drop user noam@localhost;
+drop user olga@localhost;
+drop user pjotr@localhost;
+drop user quintessa@localhost;
+
+drop database mysqltest1;
+
+disconnect root;
+
+connection default;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index e906e514074..6ee1167621a 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -1,5 +1,5 @@
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates.
-# Copyright (c) 2009-2011, Monty Program Ab
+# Copyright (c) 2005, 2011, Oracle and/or its affiliates.
+# 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 Library General Public
@@ -291,6 +291,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
#
@@ -481,7 +490,6 @@
obj:/lib*/ld-*.so
obj:/lib*/libdl-*.so
fun:dlclose
- fun:_ZL15free_plugin_memP12st_plugin_dl
}
{
@@ -1264,3 +1272,13 @@
fun:my_b_flush_io_cache
fun:_Z8filesortP3THDP5TABLEP13st_sort_fieldjP10SQL_SELECTybPy
}
+
+{
+ Problem with udf and libresolve
+ Memcheck:Cond
+ obj:*/libresolv*.so
+ fun:__libc_res_nquery
+ fun:_nss_dns_gethostbyaddr2_r
+ fun:_nss_dns_gethostbyaddr_r
+ fun:gethostbyaddr_r
+}
diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
index 9e47c7c5f19..bf70b4615c1 100644
--- a/mysys/CMakeLists.txt
+++ b/mysys/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2011, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/mysys/charset.c b/mysys/charset.c
index e3c5c945500..cc1d0a0111e 100644
--- a/mysys/charset.c
+++ b/mysys/charset.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/errors.c b/mysys/errors.c
index fe0122c2e94..bf7299ce4c6 100644
--- a/mysys/errors.c
+++ b/mysys/errors.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c
index c84a41bbec9..f9e51e48189 100644
--- a/mysys/mf_iocache.c
+++ b/mysys/mf_iocache.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index 4321a3aa072..b65e230c9a2 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/mf_loadpath.c b/mysys/mf_loadpath.c
index 0b24731f2a7..7bad535585a 100644
--- a/mysys/mf_loadpath.c
+++ b/mysys/mf_loadpath.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c
index f2bd029e522..1054db6cee4 100644
--- a/mysys/my_alloc.c
+++ b/mysys/my_alloc.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index 8328efea8ac..83d03177eba 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -1,6 +1,6 @@
/*
Copyright (c) 2001, 2011, Oracle and/or its affiliates.
- Copyright (C) 2009, 2011, Monty Program Ab
+ 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
diff --git a/mysys/my_copy.c b/mysys/my_copy.c
index 802913b141f..21de1e953a2 100644
--- a/mysys/my_copy.c
+++ b/mysys/my_copy.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_file.c b/mysys/my_file.c
index bb81fd5f06b..8d01285a94b 100644
--- a/mysys/my_file.c
+++ b/mysys/my_file.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c
index 21bbdfef997..b01b109c666 100644
--- a/mysys/my_gethwaddr.c
+++ b/mysys/my_gethwaddr.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2004, 2010, Oracle and/or its affiliates.
+/*
+ Copyright (c) 2004, 2010, Oracle and/or its affiliates
Copyright (c) 2011, Monty Program Ab
This program is free software; you can redistribute it and/or modify
diff --git a/mysys/my_getncpus.c b/mysys/my_getncpus.c
index a17d8812e04..cc2c3843e0e 100644
--- a/mysys/my_getncpus.c
+++ b/mysys/my_getncpus.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c
index ea09370280e..facc1569943 100644
--- a/mysys/my_getopt.c
+++ b/mysys/my_getopt.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c
index bc21b07e24d..ece0c5fdd87 100644
--- a/mysys/my_getsystime.c
+++ b/mysys/my_getsystime.c
@@ -26,6 +26,11 @@ static ulonglong query_performance_frequency;
#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
diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c
index 3552081b85f..444ed4273b5 100644
--- a/mysys/my_getwd.c
+++ b/mysys/my_getwd.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_handler_errors.h b/mysys/my_handler_errors.h
index 7e5f4ce12f0..551077a81ee 100644
--- a/mysys/my_handler_errors.h
+++ b/mysys/my_handler_errors.h
@@ -1,7 +1,8 @@
#ifndef MYSYS_MY_HANDLER_ERRORS_INCLUDED
#define MYSYS_MY_HANDLER_ERRORS_INCLUDED
-/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2008 MySQL AB
+ Use is subject to license terms.
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
diff --git a/mysys/my_init.c b/mysys/my_init.c
index 6a56396bd5a..abb0c0d7824 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c
index 82fbe3a63f7..1a9caf71380 100644
--- a/mysys/my_malloc.c
+++ b/mysys/my_malloc.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_redel.c b/mysys/my_redel.c
index 7f4e95f4f74..d15dd87001a 100644
--- a/mysys/my_redel.c
+++ b/mysys/my_redel.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_seek.c b/mysys/my_seek.c
index 505aec0a3c0..1033d7ac806 100644
--- a/mysys/my_seek.c
+++ b/mysys/my_seek.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_static.c b/mysys/my_static.c
index 5b088704acc..73af96d87d2 100644
--- a/mysys/my_static.c
+++ b/mysys/my_static.c
@@ -1,4 +1,6 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000-2008 MySQL AB, 2009 Sun Microsystems, Inc.
+ Use is subject to license terms.
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
diff --git a/mysys/my_symlink.c b/mysys/my_symlink.c
index 7fe7a92f54e..67b9e7d961f 100644
--- a/mysys/my_symlink.c
+++ b/mysys/my_symlink.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2001, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/my_sync.c b/mysys/my_sync.c
index a18f82bcf64..3853d30632e 100644
--- a/mysys/my_sync.c
+++ b/mysys/my_sync.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2003, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index a7b71a0bca6..91654a23071 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2001, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index adce7407239..0dfde4ca257 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 61f18d9dddf..8b30c93b2ec 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -94,8 +95,8 @@ ulong locks_immediate = 0L, locks_waited = 0L;
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 */
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
index d268fb618d5..45f4220c835 100644
--- a/mysys/thr_mutex.c
+++ b/mysys/thr_mutex.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
Copyright (c) 2010, 2011, Monty Program Ab
This program is free software; you can redistribute it and/or modify
diff --git a/plugin/auth_dialog/CMakeLists.txt b/plugin/auth_dialog/CMakeLists.txt
index 3e1f3579848..a6f6ee9b173 100644
--- a/plugin/auth_dialog/CMakeLists.txt
+++ b/plugin/auth_dialog/CMakeLists.txt
@@ -14,4 +14,5 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-MYSQL_ADD_PLUGIN(dialog dialog.c MODULE_ONLY)
+MYSQL_ADD_PLUGIN(dialog dialog.c ${CMAKE_SOURCE_DIR}/libmysql/get_password.c
+ MODULE_ONLY)
diff --git a/plugin/auth_dialog/dialog.c b/plugin/auth_dialog/dialog.c
index 9f974f6898f..2026369bc26 100644
--- a/plugin/auth_dialog/dialog.c
+++ b/plugin/auth_dialog/dialog.c
@@ -43,7 +43,7 @@
To support all this variety, the dialog plugin has a callback function
"authentication_dialog_ask". If the client has a function of this name
dialog plugin will use it for communication with the user. Otherwise
- a default fgets() based implementation will be used.
+ a default implementation will be used.
*/
static mysql_authentication_dialog_ask_t ask;
@@ -52,13 +52,25 @@ static char *builtin_ask(MYSQL *mysql __attribute__((unused)),
const char *prompt,
char *buf, int buf_len)
{
- char *ptr;
fputs(prompt, stdout);
fputc(' ', stdout);
- if (fgets(buf, buf_len, stdin) == NULL)
- return NULL;
- if ((ptr= strchr(buf, '\n')))
- *ptr= 0;
+
+ if (type == 2) /* password */
+ {
+ get_tty_password_buff("", buf, buf_len);
+ buf[buf_len-1]= 0;
+ }
+ else
+ {
+ if (!fgets(buf, buf_len-1, stdin))
+ buf[0]= 0;
+ else
+ {
+ int len= strlen(buf);
+ if (len && buf[len-1] == '\n')
+ buf[len-1]= 0;
+ }
+ }
return buf;
}
@@ -84,6 +96,7 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
unsigned char *pkt, cmd= 0;
int pkt_len, res;
char reply_buf[1024], *reply;
+ int first = 1;
do
{
@@ -92,13 +105,13 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
if (pkt_len < 0)
return CR_ERROR;
- if (pkt == 0)
+ if (pkt == 0 && first)
{
/*
in mysql_change_user() the client sends the first packet, so
the first vio->read_packet() does nothing (pkt == 0).
- We send the "password", assuming the client knows what it's doing.
+ We send the "password", assuming the client knows what its doing.
(in other words, the dialog plugin should be only set as a default
authentication plugin on the client if the first question
asks for a password - which will be sent in clear text, by the way)
@@ -114,10 +127,10 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
return CR_OK_HANDSHAKE_COMPLETE; /* yes. we're done */
/*
- asking for a password with an empty prompt means mysql->password
+ asking for a password in the first packet mean mysql->password, if it's set
otherwise we ask the user and read the reply
*/
- if ((cmd >> 1) == 2 && *pkt == 0)
+ if ((cmd >> 1) == 2 && first && mysql->passwd[0])
reply= mysql->passwd;
else
reply= ask(mysql, cmd >> 1, (const char *) pkt,
diff --git a/plugin/auth_pam/Makefile.am b/plugin/auth_pam/Makefile.am
new file mode 100644
index 00000000000..be20d393781
--- /dev/null
+++ b/plugin/auth_pam/Makefile.am
@@ -0,0 +1,16 @@
+EXTRA_LTLIBRARIES = auth_pam.la libauth_pam.la
+
+pkgplugindir=$(pkglibdir)/plugin
+AM_CPPFLAGS = -I$(top_srcdir)/include
+
+pkgplugin_LTLIBRARIES = @plugin_auth_pam_shared_target@
+auth_pam_la_LDFLAGS = -module -rpath $(pkgplugindir) -L$(top_builddir)/libservices -lmysqlservices -lpam
+auth_pam_la_CFLAGS = -shared -DMYSQL_DYNAMIC_PLUGIN
+auth_pam_la_SOURCES = auth_pam.c
+
+noinst_LTLIBRARIES = @plugin_auth_pam_static_target@
+libauth_pam_la_LDFLAGS = -lpam
+libauth_pam_la_SOURCES = auth_pam.c
+
+EXTRA_DIST = plug.in
+
diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c
new file mode 100644
index 00000000000..45c49975f6e
--- /dev/null
+++ b/plugin/auth_pam/auth_pam.c
@@ -0,0 +1,130 @@
+#include <mysql/plugin_auth.h>
+#include <string.h>
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+
+struct param {
+ unsigned char buf[10240], *ptr;
+ MYSQL_PLUGIN_VIO *vio;
+};
+
+static int conv(int n, const struct pam_message **msg,
+ struct pam_response **resp, void *data)
+{
+ struct param *param = (struct param *)data;
+ unsigned char *end = param->buf + sizeof(param->buf) - 1;
+ int i;
+
+ *resp = 0;
+
+ for (i = 0; i < n; i++)
+ {
+ /* if there's a message - append it to the buffer */
+ if (msg[i]->msg)
+ {
+ int len = strlen(msg[i]->msg);
+ if (len > end - param->ptr)
+ len = end - param->ptr;
+ if (len > 0)
+ {
+ memcpy(param->ptr, msg[i]->msg, len);
+ param->ptr+= len;
+ *(param->ptr)++ = '\n';
+ }
+ }
+ /* if the message style is *_PROMPT_*, meaning PAM asks a question,
+ send the accumulated text to the client, read the reply */
+ if (msg[i]->msg_style == PAM_PROMPT_ECHO_OFF ||
+ msg[i]->msg_style == PAM_PROMPT_ECHO_ON)
+ {
+ int pkt_len;
+ unsigned char *pkt;
+
+ /* allocate the response array.
+ freeing it is the responsibility of the caller */
+ if (*resp == 0)
+ {
+ *resp = calloc(sizeof(struct pam_response), n);
+ if (*resp == 0)
+ return PAM_BUF_ERR;
+ }
+
+ /* dialog plugin interprets the first byte of the packet
+ as the magic number.
+ 2 means "read the input with the echo enabled"
+ 4 means "password-like input, echo disabled"
+ C'est la vie. */
+ param->buf[0] = msg[i]->msg_style == PAM_PROMPT_ECHO_ON ? 2 : 4;
+ if (param->vio->write_packet(param->vio, param->buf, param->ptr - param->buf - 1))
+ return PAM_CONV_ERR;
+
+ pkt_len = param->vio->read_packet(param->vio, &pkt);
+ if (pkt_len < 0)
+ return PAM_CONV_ERR;
+ /* allocate and copy the reply to the response array */
+ (*resp)[i].resp = strndup((char*)pkt, pkt_len);
+ param->ptr = param->buf + 1;
+ }
+ }
+ return PAM_SUCCESS;
+}
+
+#define DO(X) if ((status = (X)) != PAM_SUCCESS) goto end
+
+static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info)
+{
+ pam_handle_t *pamh = NULL;
+ int status;
+ const char *new_username;
+ struct param param;
+ struct pam_conv c = { &conv, &param };
+
+ /*
+ get the service name, as specified in
+
+ CREATE USER ... IDENTIFIED WITH pam_auth AS "service"
+ */
+ const char *service = info->auth_string && info->auth_string[0]
+ ? info->auth_string : "mysql";
+
+ param.ptr = param.buf + 1;
+ param.vio = vio;
+
+ DO( pam_start(service, info->user_name, &c, &pamh) );
+ DO( pam_authenticate (pamh, 0) );
+ DO( pam_acct_mgmt(pamh, 0) );
+ DO( pam_get_item(pamh, PAM_USER, (const void**)&new_username) );
+
+ if (new_username && strcmp(new_username, info->user_name))
+ strncpy(info->authenticated_as, new_username,
+ sizeof(info->authenticated_as));
+
+end:
+ pam_end(pamh, status);
+ return status == PAM_SUCCESS ? CR_OK : CR_ERROR;
+}
+
+static struct st_mysql_auth pam_info =
+{
+ MYSQL_AUTHENTICATION_INTERFACE_VERSION,
+ "dialog",
+ pam_auth
+};
+
+maria_declare_plugin(pam)
+{
+ MYSQL_AUTHENTICATION_PLUGIN,
+ &pam_info,
+ "pam",
+ "Sergei Golubchik",
+ "PAM based authentication",
+ PLUGIN_LICENSE_GPL,
+ NULL,
+ NULL,
+ 0x0100,
+ NULL,
+ NULL,
+ "1.0",
+ MariaDB_PLUGIN_MATURITY_BETA
+}
+maria_declare_plugin_end;
diff --git a/plugin/auth_pam/plug.in b/plugin/auth_pam/plug.in
new file mode 100644
index 00000000000..05af6ce6461
--- /dev/null
+++ b/plugin/auth_pam/plug.in
@@ -0,0 +1,4 @@
+MYSQL_PLUGIN(auth_pam, [PAM Authentication Plugin], [PAM Authentication Plugin])
+MYSQL_PLUGIN_DYNAMIC(auth_pam, [auth_pam.la])
+
+AC_CHECK_HEADER([security/pam_appl.h],,[MYSQL_PLUGIN_WITHOUT(auth_pam)])
diff --git a/plugin/auth_pam/testing/pam_mariadb_mtr.c b/plugin/auth_pam/testing/pam_mariadb_mtr.c
new file mode 100644
index 00000000000..73defe30112
--- /dev/null
+++ b/plugin/auth_pam/testing/pam_mariadb_mtr.c
@@ -0,0 +1,87 @@
+/*
+ Pam module to test pam authentication plugin. Used in pam.test.
+ Linux only.
+
+ Compile as
+
+ gcc pam_mariadb_mtr.c -shared -lpam -fPIC -o pam_mariadb_mtr.so
+
+ Install as appropriate (for example, in /lib/security/).
+ Create /etc/pam.d/mariadb_mtr with
+=========================================================
+auth required pam_mariadb_mtr.so pam_test
+account required pam_mariadb_mtr.so
+=========================================================
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <security/pam_modules.h>
+#include <security/pam_appl.h>
+
+#define N 3
+
+PAM_EXTERN int
+pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+ struct pam_conv *conv;
+ struct pam_response *resp = 0;
+ int pam_err, retval = PAM_SYSTEM_ERR;
+ struct pam_message msg[N] = {
+ { PAM_TEXT_INFO, "Challenge input first." },
+ { PAM_PROMPT_ECHO_ON, "Enter:" },
+ { PAM_ERROR_MSG, "Now, the magic number!" }
+ };
+ const struct pam_message *msgp[N] = { msg, msg+1, msg+2 };
+ char *r1 = 0, *r2 = 0;
+
+ pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
+ if (pam_err != PAM_SUCCESS)
+ goto ret;
+
+ pam_err = (*conv->conv)(N, msgp, &resp, conv->appdata_ptr);
+
+ if (pam_err != PAM_SUCCESS || !resp || !((r1= resp[1].resp)))
+ goto ret;
+
+ free(resp);
+
+ msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0].msg = "PIN:";
+ pam_err = (*conv->conv)(1, msgp, &resp, conv->appdata_ptr);
+
+ if (pam_err != PAM_SUCCESS || !resp || !((r2= resp[0].resp)))
+ goto ret;
+
+ if (strlen(r1) == atoi(r2) % 100)
+ retval = PAM_SUCCESS;
+ else
+ retval = PAM_AUTH_ERR;
+
+ if (argc > 0 && argv[0])
+ pam_set_item(pamh, PAM_USER, argv[0]);
+
+ret:
+ free(resp);
+ free(r1);
+ free(r2);
+ return retval;
+}
+
+PAM_EXTERN int
+pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN int
+pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char *argv[])
+{
+
+ return PAM_SUCCESS;
+}
+
diff --git a/plugin/feedback/feedback.h b/plugin/feedback/feedback.h
index 74fb806fac2..c5acbb5ef72 100644
--- a/plugin/feedback/feedback.h
+++ b/plugin/feedback/feedback.h
@@ -13,7 +13,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#define MYSQL_SERVER
+#define MYSQL_SERVER 1
#include <sql_class.h>
namespace feedback {
diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c
index b58f3e9eda5..981335bddd6 100644
--- a/plugin/fulltext/plugin_example.c
+++ b/plugin/fulltext/plugin_example.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2005, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/scripts/make_win_bin_dist b/scripts/make_win_bin_dist
index f402d8ec8ee..a6bf73ca0fe 100755
--- a/scripts/make_win_bin_dist
+++ b/scripts/make_win_bin_dist
@@ -1,5 +1,5 @@
#!/bin/sh
-# Copyright (C) 2006 MySQL AB
+# Copyright (c) 2006, 2011, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
index 0454654ad1d..f0b09cc3e77 100644
--- a/scripts/mysql_install_db.sh
+++ b/scripts/mysql_install_db.sh
@@ -1,6 +1,6 @@
#!/bin/sh
# Copyright (c) 2000-2008 MySQL AB, 2009, 2010 Sun Microsystems, Inc.
-# Copyright (C) 2002-2003 MySQL AB & Monty Program Ab
+# Copyright (c) 2009-2011 Monty Program Ab
# Use is subject to license terms.
#
# This program is free software; you can redistribute it and/or modify
diff --git a/scripts/mysql_secure_installation.pl.in b/scripts/mysql_secure_installation.pl.in
index 543b8d1b1c0..ca39420952b 100755
--- a/scripts/mysql_secure_installation.pl.in
+++ b/scripts/mysql_secure_installation.pl.in
@@ -1,7 +1,7 @@
#!/usr/bin/perl
# -*- cperl -*-
#
-# Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2010, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/scripts/mysql_secure_installation.sh b/scripts/mysql_secure_installation.sh
index d5ace68ea76..772a9d8b1d8 100644
--- a/scripts/mysql_secure_installation.sh
+++ b/scripts/mysql_secure_installation.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-# Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2010, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/scripts/mysql_system_tables.sql b/scripts/mysql_system_tables.sql
index c8e0aa7b435..2e97d2b8272 100644
--- a/scripts/mysql_system_tables.sql
+++ b/scripts/mysql_system_tables.sql
@@ -1,6 +1,7 @@
--- Copyright (C) 2008, 2011 Oracle and/or its affiliates.
--- Copyright (C) 2010, 2011 Monty Program Ab
---
+-- Copyright (c) 2007, 2008 MySQL AB, 2009 Sun Microsystems, Inc.
+-- Copyright (c) 2008-2011 Monty Program Ab
+-- Use is subject to license terms.
+--
-- 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.
diff --git a/scripts/mysql_system_tables_data.sql b/scripts/mysql_system_tables_data.sql
index a3b6f6cbfef..878555e9458 100644
--- a/scripts/mysql_system_tables_data.sql
+++ b/scripts/mysql_system_tables_data.sql
@@ -1,4 +1,5 @@
--- Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+-- Copyright (c) 2007 MySQL AB, 2008 Sun Microsystems, Inc.
+-- Use is subject to license terms.
--
-- 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
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 9d2571b201f..02316d218e7 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -1,4 +1,21 @@
#!/usr/bin/perl
+# Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+# Copyright (c) 2000-2011 Monty Program Ab, Jani Tolonen
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free
+# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
+# MA 02110-1301, USA
# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
#
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index b7fb73cf1dd..48aefbd8c49 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -1,6 +1,6 @@
#!/usr/bin/perl
-# Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2000, 2010, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public
diff --git a/scripts/mytop.sh b/scripts/mytop.sh
index 5c88cf580a4..7cec85e2136 100755
--- a/scripts/mytop.sh
+++ b/scripts/mytop.sh
@@ -830,6 +830,11 @@ sub GetData()
%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};
@@ -926,7 +931,7 @@ sub GetData()
$lines_left--;
- printf " Queries: %-6s qps: %4.0f Slow: %7s Se/In/Up/De(%%): %02.0f/%02.0f/%02.0f/%02.0f \n",
+ 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
@@ -944,7 +949,7 @@ sub GetData()
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",
+ 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)
@@ -1014,6 +1019,35 @@ sub GetData()
}
$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,
diff --git a/sql-common/client.c b/sql-common/client.c
index 638dab9afc4..3e9a4592853 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2003, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql-common/my_time.c b/sql-common/my_time.c
index 83271aa91a0..3476401792c 100644
--- a/sql-common/my_time.c
+++ b/sql-common/my_time.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2004, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index ce6c96e55f2..50ba3712fb8 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2011, Oracle and/or its affiliates.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/sql/authors.h b/sql/authors.h
index 018c8fabc31..84c29f8c127 100644
--- a/sql/authors.h
+++ b/sql/authors.h
@@ -1,7 +1,7 @@
#ifndef AUTHORS_INCLUDED
#define AUTHORS_INCLUDED
-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2005, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc
index 95f512983da..a789763dd25 100644
--- a/sql/debug_sync.cc
+++ b/sql/debug_sync.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2009, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/debug_sync.h b/sql/debug_sync.h
index 930e6c35be9..50881f491fe 100644
--- a/sql/debug_sync.h
+++ b/sql/debug_sync.h
@@ -1,7 +1,7 @@
#ifndef DEBUG_SYNC_INCLUDED
#define DEBUG_SYNC_INCLUDED
-/* Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2009, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/derror.cc b/sql/derror.cc
index 23319ac0c99..baf7163790d 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -153,7 +153,6 @@ bool read_texts(const char *file_name, const char *language,
char lang_path[FN_REFLEN];
uchar *buff;
uchar head[32],*pos;
- const char *errmsg;
DBUG_ENTER("read_texts");
*point= 0;
@@ -231,20 +230,10 @@ Error message file '%s' had only %d error messages, but it should contain at lea
DBUG_RETURN(i);
err:
- switch (funktpos) {
- case 3:
- errmsg= "Not enough memory for messagefile '%s'";
- break;
- case 2:
- errmsg= "Incompatible header in messagefile '%s'. Probably from another version of MariaDB";
- case 1:
- errmsg= "Can't read from messagefile '%s'";
- break;
- default:
- errmsg= "Can't find messagefile '%s'";
- break;
- }
- sql_print_error(errmsg, name);
+ sql_print_error((funktpos == 3) ? "Not enough memory for messagefile '%s'" :
+ (funktpos == 2) ? "Incompatible header in messagefile '%s'. Probably from another version of MariaDB" :
+ ((funktpos == 1) ? "Can't read from messagefile '%s'" :
+ "Can't find messagefile '%s'"), name);
if (file != FERR)
(void) mysql_file_close(file, MYF(MY_WME));
DBUG_RETURN(1);
diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc
index eabe215bc3a..c41194d1a8d 100644
--- a/sql/event_data_objects.cc
+++ b/sql/event_data_objects.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc
index 8099d87b580..0eb65cff91e 100644
--- a/sql/event_db_repository.cc
+++ b/sql/event_db_repository.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2006, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_db_repository.h b/sql/event_db_repository.h
index bb708b2b520..a2862790be1 100644
--- a/sql/event_db_repository.h
+++ b/sql/event_db_repository.h
@@ -1,8 +1,6 @@
#ifndef _EVENT_DB_REPOSITORY_H_
#define _EVENT_DB_REPOSITORY_H_
-
-/*
- Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -78,7 +76,6 @@ public:
bool
create_event(THD *thd, Event_parse_data *parse_data, bool create_if_not,
bool *event_already_exists);
-
bool
update_event(THD *thd, Event_parse_data *parse_data, LEX_STRING *new_dbname,
LEX_STRING *new_name);
diff --git a/sql/event_parse_data.cc b/sql/event_parse_data.cc
index b53e366e27c..ad812a6aa5d 100644
--- a/sql/event_parse_data.cc
+++ b/sql/event_parse_data.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2008, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/event_parse_data.h b/sql/event_parse_data.h
index 1ea22edf488..faf42db623a 100644
--- a/sql/event_parse_data.h
+++ b/sql/event_parse_data.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2008, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/events.cc b/sql/events.cc
index 00299463dba..8b4bab9e3a6 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -360,8 +360,8 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
parse_data->name,
new_element)))
{
- if (!db_repository->drop_event(thd, parse_data->dbname, parse_data->name,
- TRUE))
+ if (!db_repository->drop_event(thd, parse_data->dbname,
+ parse_data->name, TRUE))
dropped= 1;
delete new_element;
}
@@ -383,16 +383,19 @@ Events::create_event(THD *thd, Event_parse_data *parse_data,
String log_query;
if (create_query_string(thd, &log_query))
{
- sql_print_error("Event Error: An error occurred while creating query string, "
- "before writing it into binary log.");
+ sql_print_error("Event Error: An error occurred while creating query "
+ "string, before writing it into binary log.");
ret= true;
}
else
+ {
/*
- If the definer is not set or set to CURRENT_USER, the value of CURRENT_USER
- will be written into the binary log as the definer for the SQL thread.
+ If the definer is not set or set to CURRENT_USER, the value
+ of CURRENT_USER will be written into the binary log as the
+ definer for the SQL thread.
*/
ret= write_bin_log(thd, TRUE, log_query.ptr(), log_query.length());
+ }
}
}
/* Restore the state of binlog format */
diff --git a/sql/field.cc b/sql/field.cc
index 480d36c2e28..84ee0f8b15a 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009-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
diff --git a/sql/field.h b/sql/field.h
index 84d60012a85..fee141d30b0 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1,7 +1,7 @@
#ifndef FIELD_INCLUDED
#define FIELD_INCLUDED
/* Copyright (c) 2000, 2011 Oracle and/or its affiliates.
- Copyright (c) 2009-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
@@ -2277,6 +2277,23 @@ public:
uchar *from_null_ptr,*to_null_ptr;
bool *null_row;
uint from_bit,to_bit;
+ /**
+ Number of bytes in the fields pointed to by 'from_ptr' and
+ 'to_ptr'. Usually this is the number of bytes that are copied from
+ 'from_ptr' to 'to_ptr'.
+
+ For variable-length fields (VARCHAR), the first byte(s) describe
+ the actual length of the text. For VARCHARs with length
+ < 256 there is 1 length byte
+ >= 256 there is 2 length bytes
+ Thus, if from_field is VARCHAR(10), from_length (and in most cases
+ to_length) is 11. For VARCHAR(1024), the length is 1026. @see
+ Field_varstring::length_bytes
+
+ Note that for VARCHARs, do_copy() will be do_varstring*() which
+ only copies the length-bytes (1 or 2) + the actual length of the
+ text instead of from/to_length bytes. @see get_copy_func()
+ */
uint from_length,to_length;
Field *from_field,*to_field;
String tmp; // For items
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 8808d73f622..89ac499b6c0 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -250,6 +251,25 @@ 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)
@@ -640,7 +660,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())
@@ -731,15 +759,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;
- if (to_length != from_length)
- 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
- return (((Field_varstring*) from)->length_bytes == 1 ?
- do_varstring1 : do_varstring2);
+ 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 ?
diff --git a/sql/filesort.cc b/sql/filesort.cc
index a9db198e9d3..f9fe0d731cd 100644
--- a/sql/filesort.cc
+++ b/sql/filesort.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -879,7 +880,7 @@ static void make_sortkey(register SORTPARAM *param,
if (sort_field->need_strxnfrm)
{
char *from=(char*) res->ptr();
- uint tmp_length;
+ uint tmp_length __attribute__((unused));
if ((uchar*) from == to)
{
set_if_smaller(length,sort_field->length);
@@ -1006,10 +1007,21 @@ static void make_sortkey(register SORTPARAM *param,
if (addonf->null_bit && field->is_null())
{
nulls[addonf->null_offset]|= addonf->null_bit;
+#ifdef HAVE_valgrind
+ bzero(to, addonf->length);
+#endif
}
else
{
+#ifdef HAVE_valgrind
+ uchar *end= field->pack(to, field->ptr);
+ uint length= (uint) ((to + addonf->length) - end);
+ DBUG_ASSERT((int) length >= 0);
+ if (length)
+ bzero(end, length);
+#else
(void) field->pack(to, field->ptr);
+#endif
}
to+= addonf->length;
}
diff --git a/sql/gcalc_slicescan.cc b/sql/gcalc_slicescan.cc
index cc2b26a8665..cd3717f186a 100644
--- a/sql/gcalc_slicescan.cc
+++ b/sql/gcalc_slicescan.cc
@@ -408,7 +408,7 @@ static int de_weak_check(long double a, long double b, long double ex)
static int de_check(long double a, long double b)
{
- return de_weak_check(a, b, (long double) 1e-10);
+ return de_weak_check(a, b, (long double) 1e-9);
}
#endif /*GCALC_CHECK_WITH_FLOAT*/
@@ -434,7 +434,7 @@ void gcalc_mul_coord(Gcalc_internal_coord *result, int result_len,
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_DIG_BASE);
+ carry= (gcalc_digit_t) (mul / (gcalc_coord2) GCALC_DIG_BASE);
} while (n_b--);
if (carry)
{
@@ -794,10 +794,51 @@ static int cmp_intersections(const Gcalc_heap::Info *i1,
/* 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)
{
- double abs= fabs(x);
Info *result= (Info *)new_item();
if (!result)
return NULL;
@@ -808,17 +849,8 @@ Gcalc_heap::Info *Gcalc_heap::new_point_info(double x, double y,
result->shape= shape;
result->top_node= 1;
result->type= nt_shape_node;
- if (m_n_points)
- {
- if (abs > coord_extent)
- coord_extent= abs;
- }
- else
- coord_extent= abs;
-
- abs= fabs(y);
- if (abs > coord_extent)
- coord_extent= abs;
+ gcalc_set_double(result->ix, x, coord_extent);
+ gcalc_set_double(result->iy, y, coord_extent);
m_n_points++;
return result;
@@ -929,32 +961,12 @@ static int compare_point_info(const void *e0, const void *e1)
}
-#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::prepare_operation()
{
Info *cur;
GCALC_DBUG_ASSERT(m_hook);
- coord_extent= find_scale(coord_extent);
-#ifdef GCALC_CHECK_WITH_FLOAT
- gcalc_coord_extent= &coord_extent;
-#endif /*GCALC_CHECK_WITH_FLOAT*/
*m_hook= NULL;
m_hook= NULL; /* just to check it's not called twice */
- for (cur= get_first(); cur; cur= cur->get_next())
- {
- gcalc_set_double(cur->ix, cur->x, coord_extent);
- gcalc_set_double(cur->iy, cur->y, coord_extent);
- }
m_first= sort_list(compare_point_info, m_first, m_n_points);
/* TODO - move this to the 'normal_scan' loop */
@@ -992,18 +1004,28 @@ int Gcalc_shape_transporter::int_add_point(gcalc_shape_info Info,
double x, double y)
{
Gcalc_heap::Info *point;
- GCALC_DBUG_ASSERT(!m_prev || m_prev->x != x || m_prev->y != y);
+ 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;
}
@@ -1031,10 +1053,20 @@ void Gcalc_shape_transporter::int_complete()
return;
}
- GCALC_DBUG_ASSERT(m_prev->x != m_first->x || m_prev->y != m_first->y);
/* polygon */
- m_first->right= m_prev;
- m_prev->left= m_first;
+ 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;
+ }
}
diff --git a/sql/gcalc_slicescan.h b/sql/gcalc_slicescan.h
index 9fc4cea5199..55de497f1ee 100644
--- a/sql/gcalc_slicescan.h
+++ b/sql/gcalc_slicescan.h
@@ -229,7 +229,9 @@ public:
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();
@@ -242,6 +244,8 @@ public:
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;
@@ -269,6 +273,7 @@ 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:
diff --git a/sql/gcalc_tools.cc b/sql/gcalc_tools.cc
index 187acbacc4c..864437401b7 100644
--- a/sql/gcalc_tools.cc
+++ b/sql/gcalc_tools.cc
@@ -650,15 +650,6 @@ Gcalc_operation_reducer(Gcalc_function *fn, modes mode, size_t blk_size) :
}
-#ifdef TMP_BLOCK
-void Gcalc_operation_reducer::res_point::set(const Gcalc_scan_iterator *si)
-{
- if ((intersection_point= si->intersection_step()))
- ii= si->get_cur_ii();
- else
- pi= si->get_cur_pi();
-}
-#endif /*TMP_BLOCK*/
void Gcalc_operation_reducer::res_point::set(const Gcalc_scan_iterator *si)
{
intersection_point= si->intersection_step();
@@ -1362,6 +1353,10 @@ int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage)
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;
@@ -1412,6 +1407,7 @@ int Gcalc_operation_reducer::get_result(Gcalc_result_receiver *storage)
}
}
+done:
m_res_hook= (Gcalc_dyn_list::Item **)&m_result;
storage->done();
GCALC_DBUG_RETURN(0);
diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc
index e2ced8c8326..7b50b26c6ca 100644
--- a/sql/gen_lex_hash.cc
+++ b/sql/gen_lex_hash.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -85,7 +85,6 @@ So, we can read full search-structure as 32-bit word
#include <stdio.h>
#include <string.h>
-#include <welcome_copyright_notice.h> /* ORACLE_WELCOME_COPYRIGHT_NOTICE */
struct hash_lex_struct
{
@@ -377,9 +376,25 @@ int main(int argc,char **argv)
/* Broken up to indicate that it's not advice to you, gentle reader. */
printf("/*\n\n Do " "not " "edit " "this " "file " "directly!\n\n*/\n");
- puts("/*");
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
- puts("*/");
+ printf("\
+/* Copyright (C) 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.\n\
+ Copyright (C) 2008-2011 Oracle\n\
+\n\
+ This program is free software; you can redistribute it and/or modify\n\
+ it under the terms of the GNU General Public License as published by\n\
+ the Free Software Foundation; version 2 of the License.\n\
+\n\
+ This program is distributed in the hope that it will be useful,\n\
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
+ GNU General Public License for more details.\n\
+\n\
+ You should have received a copy of the GNU General Public License\n\
+ along with this program; see the file COPYING. If not, write to the\n\
+ Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston\n\
+ MA 02110-1301 USA. */\n\
+\n\
+");
/* Broken up to indicate that it's not advice to you, gentle reader. */
printf("/* Do " "not " "edit " "this " "file! This is generated by "
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 7a62efb1917..2878f25ed14 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2004, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc
index 3d140b92977..f91e19df08e 100644
--- a/sql/ha_ndbcluster_binlog.cc
+++ b/sql/ha_ndbcluster_binlog.cc
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index a1e45b36b82..1f6c81cd459 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/ha_partition.h b/sql/ha_partition.h
index 46a8924c883..8723682904a 100644
--- a/sql/ha_partition.h
+++ b/sql/ha_partition.h
@@ -2,7 +2,7 @@
#define HA_PARTITION_INCLUDED
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/handler.cc b/sql/handler.cc
index 1d0f676493d..8c2756977cf 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -2879,7 +2879,23 @@ void handler::print_error(int error, myf errflag)
char key[MAX_KEY_LENGTH];
String str(key,sizeof(key),system_charset_info);
/* Table is opened and defined at this point */
- key_unpack(&str,table,(uint) key_nr);
+
+ /*
+ Use primary_key instead of key_nr because key_nr is a key
+ number in the child FK table, not in our 'table'. See
+ Bug#12661768 UPDATE IGNORE CRASHES SERVER IF TABLE IS INNODB
+ AND IT IS PARENT FOR OTHER ONE This bug gets a better fix in
+ MySQL 5.6, but it is too risky to get that in 5.1 and 5.5
+ (extending the handler interface and adding new error message
+ codes)
+ */
+ if (table->s->primary_key < MAX_KEY)
+ key_unpack(&str,table,table->s->primary_key);
+ else
+ {
+ LEX_CUSTRING tmp= {USTRING_WITH_LEN("Unknown key value")};
+ str.set((const char*) tmp.str, tmp.length, system_charset_info);
+ }
max_length= (MYSQL_ERRMSG_SIZE-
(uint) strlen(ER(ER_FOREIGN_DUPLICATE_KEY)));
if (str.length() >= max_length)
@@ -2887,15 +2903,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;
@@ -2965,21 +2981,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:
@@ -2991,7 +3007,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:
@@ -3032,12 +3048,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
@@ -3045,15 +3061,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_VOID_RETURN;
}
diff --git a/sql/item.cc b/sql/item.cc
index 028cc8c8e30..02cbe9b7f49 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -4227,7 +4227,7 @@ String* Item_ref_null_helper::val_str(String* s)
bool Item_ref_null_helper::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{
- return (owner->was_null|= null_value= (*ref)->get_date(ltime, fuzzydate));
+ return (owner->was_null|= null_value= (*ref)->get_date_result(ltime, fuzzydate));
}
@@ -8654,6 +8654,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)
@@ -9090,6 +9104,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))
{
diff --git a/sql/item.h b/sql/item.h
index 9186ba084db..8b452c303d6 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1150,6 +1150,10 @@ public:
virtual bool eval_not_null_tables(uchar *opt_arg) { return 0; }
virtual bool clear_sum_processor(uchar *opt_arg) { return 0; }
virtual bool is_subquery_processor (uchar *opt_arg) { return 0; }
+ virtual bool limit_index_condition_pushdown_processor(uchar *opt_arg)
+ {
+ return FALSE;
+ }
/* To call bool function for all arguments */
struct bool_func_call_args
@@ -3885,6 +3889,7 @@ public:
return false;
return example->is_expensive_processor(arg);
}
+ virtual void set_null();
};
@@ -4055,6 +4060,7 @@ public:
DBUG_VOID_RETURN;
}
bool cache_value();
+ virtual void set_null();
};
diff --git a/sql/item_buff.cc b/sql/item_buff.cc
index e72c63daf7d..86e0fd32774 100644
--- a/sql/item_buff.cc
+++ b/sql/item_buff.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 9c8d6b73e60..96837a8f262 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 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
diff --git a/sql/item_create.h b/sql/item_create.h
index a8a8b9d97dd..ac6b0f8454f 100644
--- a/sql/item_create.h
+++ b/sql/item_create.h
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
- Copyright (c) 2010, 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
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 1d3a32ba4f1..034ffbea344 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
- Copyright (c) 2011 Monty Program Ab
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ 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
diff --git a/sql/item_func.h b/sql/item_func.h
index 8e9fbd9af5c..f5c43360ee8 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1763,6 +1763,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() {}
@@ -1957,6 +1958,10 @@ public:
{
return trace_unsupported_by_check_vcol_func_processor(func_name());
}
+ bool limit_index_condition_pushdown_processor(uchar *opt_arg)
+ {
+ return TRUE;
+ }
};
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index 5ccdb198ecb..e1f06824d5b 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -1,5 +1,6 @@
-/* Copyright (c) 2000, 2010 Oracle and/or its affiliates.
- Copyright (C) 2011 Monty Program Ab.
+/*
+ Copyright (c) 2003-2007 MySQL AB, 2009, 2010 Sun Microsystems, Inc.
+ Use is subject to license terms.
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
@@ -659,140 +660,6 @@ static double distance_points(const Gcalc_heap::Info *a,
}
-/*
- Calculates the distance between objects.
-*/
-
-#ifdef TMP_BLOCK
-static int calc_distance(double *result, Gcalc_heap *collector, uint obj2_si,
- Gcalc_function *func, Gcalc_scan_iterator *scan_it)
-{
- bool above_cur_point, cur_point_edge;
- const Gcalc_scan_iterator::point *evpos;
- const Gcalc_heap::Info *cur_point= NULL;
- const Gcalc_heap::Info *dist_point;
- const Gcalc_scan_iterator::point *ev;
- double t, distance, cur_distance;
- double ex, ey, vx, vy, e_sqrlen;
- int o1, o2;
-
- DBUG_ENTER("calc_distance");
-
- above_cur_point= false;
- 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();
- cur_point= NULL;
-
- if (ev->simple_event())
- {
- cur_point= ev->pi;
- goto calculate_distance;
- }
-
- /*
- handling intersection we only need to check if it's the intersecion
- of objects 1 and 2. In this case distance is 0
- */
- o1= 0;
- o2= 0;
- for (; ev; ev= ev->get_next())
- {
- if (ev->event != scev_intersection)
- cur_point= ev->pi;
- if (ev->pi->shape >= obj2_si)
- o2= 1;
- else
- o1= 1;
- if (o1 && o2)
- {
- distance= 0;
- goto exit;
- }
- }
- if (!cur_point)
- continue;
-
-#ifdef TO_REMOVE
- goto calculate_distance;
- /*
- having these events we need to check for possible intersection
- of objects
- scev_thread | scev_two_threads | scev_single_point
- */
- DBUG_ASSERT(ev & (scev_thread | scev_two_threads | scev_single_point));
-
- func->clear_state();
- 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_state(si);
- }
- func->invert_state(evpos->get_shape());
- if (func->count())
- {
- /* Point of one object is inside the other - intersection found */
- distance= 0;
- goto exit;
- }
-#endif /*TO_REMOVE*/
-
-calculate_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->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:
- *result= distance;
- DBUG_RETURN(0);
-
-mem_error:
- DBUG_RETURN(1);
-}
-#endif /*TMP_BLOCK*/
-
-
#define GIS_ZERO 0.00000000001
longlong Item_func_spatial_rel::val_int()
@@ -806,6 +673,8 @@ longlong Item_func_spatial_rel::val_int()
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);
@@ -820,19 +689,35 @@ longlong Item_func_spatial_rel::val_int()
!(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);
@@ -843,6 +728,8 @@ longlong Item_func_spatial_rel::val_int()
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;
@@ -900,15 +787,6 @@ longlong Item_func_spatial_rel::val_int()
scan_it.init(&collector);
scan_it.killed= (int *) &(current_thd->killed);
-#ifdef TMP_BLOCK
- if (spatial_rel == SP_EQUALS_FUNC)
- {
- result= (g1->get_class_info()->m_type_id == g1->get_class_info()->m_type_id) &&
- func_equals();
- goto exit;
- }
-#endif /*TMP_BLOCK*/
-
if (func.alloc_states())
goto exit;
@@ -937,6 +815,8 @@ String *Item_func_spatial_operation::val_str(String *str_value)
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);
@@ -945,14 +825,23 @@ String *Item_func_spatial_operation::val_str(String *str_value)
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())) ||
- g1->store_shapes(&trn) || g2->store_shapes(&trn))))
+ !(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;
@@ -1376,12 +1265,18 @@ String *Item_func_buffer::val_str(String *str_value)
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= 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.
@@ -1448,6 +1343,8 @@ longlong Item_func_issimple::val_int()
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);
@@ -1456,6 +1353,8 @@ longlong Item_func_issimple::val_int()
!(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);
@@ -1684,6 +1583,8 @@ double Item_func_distance::val_real()
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 ||
@@ -1691,6 +1592,11 @@ double Item_func_distance::val_real()
!(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))
{
diff --git a/sql/item_row.cc b/sql/item_row.cc
index ccd7a37e9b7..530a40c55dc 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_row.h b/sql/item_row.h
index 1d34ecfc310..aa56068f8ba 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -1,7 +1,8 @@
#ifndef ITEM_ROW_INCLUDED
#define ITEM_ROW_INCLUDED
-/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index f570c309d79..48029863878 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 69800e7e674..8c56cea990b 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -1,7 +1,8 @@
#ifndef ITEM_STRFUNC_INCLUDED
#define ITEM_STRFUNC_INCLUDED
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index f25722ab30b..5f78cdf167b 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -188,7 +188,7 @@ void Item_allany_subselect::cleanup()
*/
for (SELECT_LEX *sl= unit->first_select();
sl; sl= sl->next_select())
- if (test_strategy(SUBS_MAXMIN_INJECTED))
+ if (test_set_strategy(SUBS_MAXMIN_INJECTED))
sl->with_sum_func= false;
Item_in_subselect::cleanup();
}
@@ -221,8 +221,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
bool res;
DBUG_ASSERT(fixed == 0);
- /* There is no reason to get a different THD. */
- DBUG_ASSERT(thd == thd_param);
+ engine->set_thd((thd= thd_param));
if (!done_first_fix_fields)
{
done_first_fix_fields= TRUE;
@@ -905,7 +904,10 @@ void Item_singlerow_subselect::reset()
{
Item_subselect::reset();
if (value)
- value->null_value= TRUE;
+ {
+ for(uint i= 0; i < engine->cols(); i++)
+ row[i]->set_null();
+ }
}
@@ -1016,6 +1018,11 @@ 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;
+ }
}
@@ -1201,7 +1208,8 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
Item_exists_subselect(),
left_expr_cache(0), first_execution(TRUE), in_strategy(SUBS_NOT_TRANSFORMED),
optimizer(0), pushed_cond_guards(NULL), emb_on_expr_nest(NULL),
- is_jtbm_merged(FALSE), is_flattenable_semijoin(FALSE),
+ is_jtbm_merged(FALSE), is_jtbm_const_tab(FALSE),
+ is_flattenable_semijoin(FALSE),
is_registered_semijoin(FALSE),
upper_item(0)
{
@@ -1674,6 +1682,13 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join)
thd->change_item_tree(it.ref(), item);
}
+ DBUG_EXECUTE("where",
+ print_where(item, "rewrite with MIN/MAX", QT_ORDINARY););
+ if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
+ {
+ 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;
/*
@@ -2906,6 +2921,7 @@ 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 (!join->optimized)
{
SELECT_LEX_UNIT *unit= select_lex->master_unit();
@@ -2914,7 +2930,7 @@ int subselect_single_select_engine::exec()
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);
}
@@ -4043,6 +4059,7 @@ ulonglong subselect_hash_sj_engine::rowid_merge_buff_size(
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);
@@ -4065,7 +4082,18 @@ ulonglong subselect_hash_sj_engine::rowid_merge_buff_size(
buff_size+= (row_count - result_sink->get_null_count_of_col(i)) *
sizeof(rownum_t);
/* Add the size of Ordered_key::null_key */
- buff_size+= bitmap_buffer_size(result_sink->get_max_null_of_col(i));
+ 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);
}
}
@@ -4181,6 +4209,8 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
*/
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() ||
@@ -5564,6 +5594,8 @@ bool subselect_rowid_merge_engine::test_null_row(rownum_t row_num)
/**
Test if a subset of NULL-able columns contains a row of NULLs.
+ @retval TRUE if such a row exists
+ @retval FALSE no complementing null row
*/
bool subselect_rowid_merge_engine::
@@ -5571,34 +5603,34 @@ exists_complementing_null_row(MY_BITMAP *keys_to_complement)
{
rownum_t highest_min_row= 0;
rownum_t lowest_max_row= UINT_MAX;
- uint count_null_keys, i, j;
+ uint count_null_keys, i;
Ordered_key *cur_key;
- count_null_keys= keys_to_complement->n_bits -
- bitmap_bits_set(keys_to_complement);
- if (count_null_keys == 1)
+ if (!count_columns_with_nulls)
{
/*
- The caller guarantees that the complement to keys_to_complement
- contains only columns with NULLs. Therefore if there is only one column,
- it is guaranteed to contain NULLs.
+ 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 TRUE;
+ return FALSE;
}
- for (i= (non_null_key ? 1 : 0), j= 0; i < merge_keys_count; i++)
+ 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;
- DBUG_ASSERT(cur_key->get_null_count());
+ 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[j++]= cur_key->get_null_key();
+ null_bitmaps[count_null_keys++]= cur_key->get_null_key();
}
- DBUG_ASSERT(count_null_keys == j);
if (lowest_max_row < highest_min_row)
{
@@ -5608,7 +5640,7 @@ exists_complementing_null_row(MY_BITMAP *keys_to_complement)
return bitmap_exists_intersection((const MY_BITMAP**) null_bitmaps,
count_null_keys,
- highest_min_row, lowest_max_row);
+ (uint)highest_min_row, (uint)lowest_max_row);
}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 6007812fa7d..57f413f1ccd 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -1,7 +1,7 @@
#ifndef ITEM_SUBSELECT_INCLUDED
#define ITEM_SUBSELECT_INCLUDED
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -241,6 +241,10 @@ public:
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_result_interceptor;
friend class Item_in_optimizer;
@@ -460,10 +464,44 @@ public:
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;
- bool is_jtbm_merged;
+
+ /*
+ (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.
*/
@@ -504,7 +542,7 @@ public:
: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_merged(FALSE), is_jtbm_const_tab(FALSE),
upper_item(0)
{}
void cleanup();
@@ -725,9 +763,9 @@ protected:
class subselect_single_select_engine: public subselect_engine
{
- bool prepared; /* simple subselect is prepared */
- bool executed; /* simple subselect is executed */
- bool optimize_error; ///< simple subselect optimization failed
+ bool prepared; /* simple subselect is prepared */
+ 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:
@@ -755,6 +793,9 @@ public:
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);
+
};
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 9bf786dbbd4..8824ec5b699 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2010, 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
diff --git a/sql/item_sum.h b/sql/item_sum.h
index c7a222bcd84..7233fe39ead 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1,7 +1,7 @@
#ifndef ITEM_SUM_INCLUDED
#define ITEM_SUM_INCLUDED
/* Copyright (c) 2000, 2011 Oracle and/or its affiliates.
- Copyright (c) 2010, 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
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 0d21d619421..30357a1bbe8 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2288,8 +2288,7 @@ String *Item_char_typecast::val_str(String *str)
cast_cs == &my_charset_bin ?
"cast_as_binary" : func_name(),
current_thd->variables.max_allowed_packet);
- null_value= 1;
- return 0;
+ cast_length= current_thd->variables.max_allowed_packet;
}
if (!charset_conversion)
@@ -2360,6 +2359,18 @@ String *Item_char_typecast::val_str(String *str)
}
}
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;
}
diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc
index b93a83c05a9..150c2c212d7 100644
--- a/sql/item_xmlfunc.cc
+++ b/sql/item_xmlfunc.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/lock.cc b/sql/lock.cc
index 57a9e753ce7..a7029548493 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -705,8 +706,10 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
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++;
@@ -734,8 +737,9 @@ MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, uint flags)
TABLE *table;
enum thr_lock_type lock_type;
THR_LOCK_DATA **locks_start;
-
- if ((table=table_ptr[i])->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE)
+ 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);
diff --git a/sql/log.cc b/sql/log.cc
index b882aab15e9..5a4d09a2744 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -3464,7 +3464,6 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd)
DBUG_ENTER("reset_logs");
ha_reset_logs(thd);
-
/*
We need to get both locks to be sure that no one is trying to
write to the index log file.
diff --git a/sql/log.h b/sql/log.h
index bad86e7615d..1e3d0698eee 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 38af12cab9f..676fa457c15 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/log_event.h b/sql/log_event.h
index 0accbd0dd1c..5c0a82b2dac 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc
index a52c584726a..49d35197d60 100644
--- a/sql/log_event_old.cc
+++ b/sql/log_event_old.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2007, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/message.h b/sql/message.h
index 8ef0032e423..dac0576d0c4 100644
--- a/sql/message.h
+++ b/sql/message.h
@@ -68,8 +68,8 @@
// MessageText:
//
// %1For more information, see Help and Support Center at http://www.mysql.com.
-//
-//
+//
+//
//
#define MSG_DEFAULT 0xC0000064L
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index 39be927fd27..21611afd87b 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/my_decimal.h b/sql/my_decimal.h
index e0c47029940..bd03782cb18 100644
--- a/sql/my_decimal.h
+++ b/sql/my_decimal.h
@@ -73,15 +73,30 @@ inline int my_decimal_int_part(uint precision, uint decimals)
class my_decimal :public decimal_t
{
+ /*
+ Several of the routines in strings/decimal.c have had buffer
+ overrun/underrun problems. These are *not* caught by valgrind.
+ To catch them, we allocate dummy fields around the buffer,
+ and test that their values do not change.
+ */
+#if !defined(DBUG_OFF)
+ int foo1;
+#endif
+
decimal_digit_t buffer[DECIMAL_BUFF_LENGTH];
+#if !defined(DBUG_OFF)
+ int foo2;
+ static const int test_value= 123;
+#endif
+
public:
my_decimal(const my_decimal &rhs) : decimal_t(rhs)
{
+ init();
for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++)
buffer[i]= rhs.buffer[i];
- fix_buffer_pointer();
}
my_decimal& operator=(const my_decimal &rhs)
@@ -97,14 +112,30 @@ public:
void init()
{
+#if !defined(DBUG_OFF)
+ foo1= test_value;
+ foo2= test_value;
+#endif
len= DECIMAL_BUFF_LENGTH;
buf= buffer;
+ TRASH_ALLOC(buffer, sizeof(buffer));
}
my_decimal()
{
init();
}
+ ~my_decimal()
+ {
+ sanity_check();
+ }
+
+ void sanity_check()
+ {
+ DBUG_ASSERT(foo1 == test_value);
+ DBUG_ASSERT(foo2 == test_value);
+ }
+
void fix_buffer_pointer() { buf= buffer; }
bool sign() const { return decimal_t::sign; }
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d3b7e1e7085..fc58866ac17 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
- Copyright (c) 2009-2011 Monty Program Ab
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ 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
@@ -275,8 +275,6 @@ extern "C" sig_handler handle_segfault(int sig);
/* Constants */
-#include <welcome_copyright_notice.h> // ORACLE_WELCOME_COPYRIGHT_NOTICE
-
const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
static const char *tc_heuristic_recover_names[]=
@@ -7220,8 +7218,14 @@ static void usage(void)
if (!default_collation_name)
default_collation_name= (char*) default_charset_info->name;
print_version();
- puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011"));
- puts("Starts the MySQL database server.\n");
+ puts("\
+Copyright (C) 2000-2008 MySQL AB, by Monty and others.\n\
+Copyright (C) 2000, 2011 Oracle.\n\
+Copyright (C) 2009-2011 Monty Program Ab.\n\
+This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
+and you are welcome to modify and redistribute it under the GPL license\n\n\
+Starts the MariaDB database server.\n");
+
printf("Usage: %s [OPTIONS]\n", my_progname);
if (!opt_verbose)
puts("\nFor more help options (several pages), use mysqld --verbose --help.");
diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc
index 12a732176a5..bec3bf6dab6 100644
--- a/sql/opt_index_cond_pushdown.cc
+++ b/sql/opt_index_cond_pushdown.cc
@@ -29,6 +29,11 @@
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;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index c6e1bf584e3..69273398585 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2010, 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
@@ -11708,6 +11708,8 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time)
DBUG_RETURN(NULL);
if (table->s->keys == 0) /* There are no indexes to use. */
DBUG_RETURN(NULL);
+ if (join->conds && join->conds->used_tables() & OUTER_REF_TABLE_BIT)
+ DBUG_RETURN(NULL); /* Cannot execute with correlated conditions. */
/* Check (SA1,SA4) and store the only MIN/MAX argument - the C attribute.*/
if (join->make_sum_func_list(join->all_fields, join->fields_list, 1))
@@ -13053,6 +13055,7 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void)
int result;
DBUG_ENTER("QUICK_GROUP_MIN_MAX_SELECT::reset");
+ seen_first_key= FALSE;
if (!head->key_read)
{
doing_key_read= 1;
diff --git a/sql/opt_range.h b/sql/opt_range.h
index cf8da1acb0d..545e9e3c7b8 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index 02a57a9e7df..3b1991d1686 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -10,7 +10,9 @@
#pragma implementation // gcc: Class implementation
#endif
+#include "sql_base.h"
#include "sql_select.h"
+#include "filesort.h"
#include "opt_subselect.h"
#include "sql_test.h"
#include <my_bit.h>
@@ -303,6 +305,14 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
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
@@ -375,14 +385,6 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
if (failure)
DBUG_RETURN(-1); /* purecov: deadcode */
}
- if (select_lex == parent_unit->fake_select_lex)
- {
- /*
- The join and its select_lex object represent the 'fake' select used
- to compute the result of a UNION.
- */
- DBUG_RETURN(0);
- }
DBUG_PRINT("info", ("Checking if subq can be converted to semi-join"));
/*
@@ -596,7 +598,7 @@ bool subquery_types_allow_materialization(Item_in_subselect *in_subs)
break;
case TIME_RESULT:
if (mysql_type_to_time_type(outer->field_type()) !=
- mysql_type_to_time_type(outer->field_type()))
+ mysql_type_to_time_type(inner->field_type()))
DBUG_RETURN(FALSE);
default:
/* suitable for materialization */
@@ -1265,10 +1267,9 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
List_iterator_fast<TABLE_LIST> si(subq_lex->leaf_tables);
while ((tl= si++))
{
- tl->table->tablenr= table_no;
- tl->table->map= ((table_map)1) << table_no;
+ tl->set_tablenr(table_no);
if (tl->is_jtbm())
- tl->jtbm_table_no= tl->table->tablenr;
+ 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;
@@ -1426,25 +1427,12 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
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;
- double rows;
- double read_time;
DBUG_ENTER("convert_subq_to_jtbm");
-
+ bool optimization_delayed= TRUE;
subq_pred->set_strategy(SUBS_MATERIALIZATION);
- if (subq_pred->optimize(&rows, &read_time))
- DBUG_RETURN(TRUE);
- subq_pred->jtbm_read_time= read_time;
- subq_pred->jtbm_record_count=rows;
subq_pred->is_jtbm_merged= TRUE;
- if (subq_pred->engine->engine_type() != subselect_engine::HASH_SJ_ENGINE)
- {
- *remove_item= FALSE;
- DBUG_RETURN(FALSE);
- }
-
-
*remove_item= TRUE;
TABLE_LIST *jtbm;
@@ -1480,7 +1468,18 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
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;
@@ -2165,227 +2164,172 @@ bool find_eq_ref_candidate(TABLE *table, table_map sj_inner_tables)
join prefixes each strategy can handle.
*/
-void advance_sj_state(JOIN *join, table_map remaining_tables,
- const JOIN_TAB *new_join_tab, uint idx,
- double *current_record_count, double *current_read_time,
+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)
{
- TABLE_LIST *emb_sj_nest;
POSITION *pos= join->positions + idx;
- remaining_tables &= ~new_join_tab->table->map;
- bool disable_jbuf= join->thd->variables.join_cache_level == 0;
-
- pos->prefix_cost.convert_from_cost(*current_read_time);
- pos->prefix_record_count= *current_record_count;
- pos->sj_strategy= SJ_OPT_NONE;
-
- pos->prefix_dups_producing_tables= join->cur_dups_producing_tables;
+ 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,
+ };
- /* We're performing optimization inside SJ-Materialization nest */
if (join->emb_sjm_nest)
{
- pos->invalidate_firstmatch_prefix();
- pos->first_loosescan_table= MAX_TABLES;
- pos->dupsweedout_tables= 0;
- pos->sjm_scan_need_tables= 0;
+ /*
+ 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;
}
- /* Initialize the state or copy it from prev. tables */
+ /*
+ 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)
{
- pos->invalidate_firstmatch_prefix();
- pos->first_loosescan_table= MAX_TABLES;
- pos->dupsweedout_tables= 0;
- pos->sjm_scan_need_tables= 0;
- LINT_INIT(pos->sjm_scan_last_inner);
+ /* First table, initialize pickers */
+ for (strategy= pickers; *strategy != NULL; strategy++)
+ (*strategy)->set_empty();
+ pos->inner_tables_handled_with_other_sjs= 0;
}
else
{
- // FirstMatch
- pos->first_firstmatch_table=
- (pos[-1].sj_strategy == SJ_OPT_FIRST_MATCH) ?
- MAX_TABLES : pos[-1].first_firstmatch_table;
- pos->first_firstmatch_rtbl= pos[-1].first_firstmatch_rtbl;
- pos->firstmatch_need_tables= pos[-1].firstmatch_need_tables;
-
- // LooseScan
- pos->first_loosescan_table=
- (pos[-1].sj_strategy == SJ_OPT_LOOSE_SCAN) ?
- MAX_TABLES : pos[-1].first_loosescan_table;
- pos->loosescan_need_tables= pos[-1].loosescan_need_tables;
-
- // SJ-Materialization Scan
- pos->sjm_scan_need_tables=
- (pos[-1].sj_strategy == SJ_OPT_MATERIALIZE_SCAN) ?
- 0 : pos[-1].sjm_scan_need_tables;
- pos->sjm_scan_last_inner= pos[-1].sjm_scan_last_inner;
-
- // Duplicate Weedout
- pos->dupsweedout_tables= pos[-1].dupsweedout_tables;
- pos->first_dupsweedout_table= pos[-1].first_dupsweedout_table;
- }
-
- table_map handled_by_fm_or_ls= 0;
- /* FirstMatch Strategy */
- if (new_join_tab->emb_sj_nest &&
- optimizer_flag(join->thd, OPTIMIZER_SWITCH_FIRSTMATCH) &&
- !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)))
+ for (strategy= pickers; *strategy != NULL; strategy++)
{
- /* Start tracking potential FirstMatch range */
- pos->first_firstmatch_table= idx;
- pos->firstmatch_need_tables= sj_inner_tables;
- pos->first_firstmatch_rtbl= remaining_tables;
+ (*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;
- if (pos->in_firstmatch_prefix())
+ for (strategy= pickers; *strategy != NULL; strategy++)
{
- if (outer_corr_tables & pos->first_firstmatch_rtbl)
+ 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))
{
/*
- 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.
+ 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.
*/
- pos->invalidate_firstmatch_prefix();
- }
- else
- {
- /* Record that we need all of this semi-join's inner tables, too */
- pos->firstmatch_need_tables|= sj_inner_tables;
- }
-
- if (pos->in_firstmatch_prefix() &&
- !(pos->firstmatch_need_tables & remaining_tables))
- {
- /*
- Got a complete FirstMatch range.
- Calculate correct costs and fanout
- */
- optimize_wo_join_buffering(join, pos->first_firstmatch_table, idx,
- remaining_tables, FALSE, idx,
- current_record_count,
- current_read_time);
- /*
- We don't yet know what are the other strategies, so pick the
- FirstMatch.
-
- We ought to save the alternate POSITIONs produced by
- optimize_wo_join_buffering but the problem is that providing save
- space uses too much space. Instead, we will re-calculate the
- alternate POSITIONs after we've picked the best QEP.
- */
- pos->sj_strategy= SJ_OPT_FIRST_MATCH;
- handled_by_fm_or_ls= pos->firstmatch_need_tables;
+ 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;
+ *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();
+ }
}
}
}
- /* LooseScan Strategy */
- {
- POSITION *first=join->positions+pos->first_loosescan_table;
- /*
- LooseScan strategy can't handle interleaving between tables from the
- semi-join that LooseScan is handling and any other tables.
-
- If we were considering LooseScan for the join prefix (1)
- and the table we're adding creates an interleaving (2)
- then
- stop considering loose scan
- */
- if ((pos->first_loosescan_table != MAX_TABLES) && // (1)
- (first->table->emb_sj_nest->sj_inner_tables & remaining_tables) && //(2)
- new_join_tab->emb_sj_nest != first->table->emb_sj_nest) //(2)
- {
- pos->first_loosescan_table= MAX_TABLES;
- }
-
- /*
- If we got an option to use LooseScan for the current table, start
- considering using LooseScan strategy
- */
- if (loose_scan_pos->read_time != DBL_MAX && !join->outer_join)
- {
- pos->first_loosescan_table= idx;
- pos->loosescan_need_tables=
- new_join_tab->emb_sj_nest->sj_inner_tables |
- new_join_tab->emb_sj_nest->nested_join->sj_depends_on |
- new_join_tab->emb_sj_nest->nested_join->sj_corr_tables;
- }
-
- if ((pos->first_loosescan_table != MAX_TABLES) &&
- !(remaining_tables & pos->loosescan_need_tables))
- {
- /*
- Ok we have LooseScan plan and also have all LooseScan sj-nest's
- inner tables and outer correlated tables into the prefix.
- */
-
- first=join->positions + pos->first_loosescan_table;
- uint n_tables= my_count_bits(first->table->emb_sj_nest->sj_inner_tables);
- /* Got a complete LooseScan range. Calculate its cost */
- /*
- The same problem as with FirstMatch - we need to save POSITIONs
- somewhere but reserving space for all cases would require too
- much space. We will re-calculate POSITION structures later on.
- */
- optimize_wo_join_buffering(join, pos->first_loosescan_table, idx,
- remaining_tables,
- TRUE, //first_alt
- disable_jbuf ? join->table_count :
- pos->first_loosescan_table + n_tables,
- current_record_count,
- current_read_time);
- /*
- We don't yet have any other strategies that could handle this
- semi-join nest (the other options are Duplicate Elimination or
- Materialization, which need at least the same set of tables in
- the join prefix to be considered) so unconditionally pick the
- LooseScan.
- */
- pos->sj_strategy= SJ_OPT_LOOSE_SCAN;
- handled_by_fm_or_ls= first->table->emb_sj_nest->sj_inner_tables;
- }
- }
-
- /*
- Update join->cur_sj_inner_tables (Used by FirstMatch in this function and
- LooseScan detector in best_access_path)
- */
if ((emb_sj_nest= new_join_tab->emb_sj_nest))
{
join->cur_sj_inner_tables |= emb_sj_nest->sj_inner_tables;
- join->cur_dups_producing_tables |= emb_sj_nest->sj_inner_tables;
/* Remove the sj_nest if all of its SJ-inner tables are in cur_table_map */
if (!(remaining_tables &
emb_sj_nest->sj_inner_tables & ~new_join_tab->table->map))
join->cur_sj_inner_tables &= ~emb_sj_nest->sj_inner_tables;
}
- join->cur_dups_producing_tables &= ~handled_by_fm_or_ls;
- /* 4. SJ-Materialization and SJ-Materialization-scan strategy handler */
+ 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,
@@ -2412,11 +2356,11 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
The simple way to model this is to remove SJM-SCAN(...) fanout once
we reach the point #2.
*/
- pos->sjm_scan_need_tables=
+ sjm_scan_need_tables=
new_join_tab->emb_sj_nest->sj_inner_tables |
new_join_tab->emb_sj_nest->nested_join->sj_depends_on |
new_join_tab->emb_sj_nest->nested_join->sj_corr_tables;
- pos->sjm_scan_last_inner= idx;
+ sjm_scan_last_inner= idx;
}
else
{
@@ -2439,34 +2383,31 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
mat_read_time += mat_info->materialization_cost.total_cost() +
prefix_rec_count * mat_info->lookup_cost.total_cost();
- if (mat_read_time < *current_read_time || join->cur_dups_producing_tables)
- {
- /*
- NOTE: When we pick to use SJM[-Scan] we don't memcpy its POSITION
- elements to join->positions as that makes it hard to return things
- back when making one step back in join optimization. That's done
- after the QEP has been chosen.
- */
- pos->sj_strategy= SJ_OPT_MATERIALIZE;
- *current_read_time= mat_read_time;
- *current_record_count= prefix_rec_count;
- join->cur_dups_producing_tables&=
- ~new_join_tab->emb_sj_nest->sj_inner_tables;
- }
+ /*
+ 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 (pos->sjm_scan_need_tables && /* Have SJM-Scan prefix */
- !(pos->sjm_scan_need_tables & remaining_tables))
+ if (sjm_scan_need_tables && /* Have SJM-Scan prefix */
+ !(sjm_scan_need_tables & remaining_tables))
{
TABLE_LIST *mat_nest=
- join->positions[pos->sjm_scan_last_inner].table->emb_sj_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= pos->sjm_scan_last_inner + 1 - mat_info->tables;
+ int first_tab= sjm_scan_last_inner + 1 - mat_info->tables;
/* Get the prefix cost */
if (first_tab == (int)join->const_tables)
{
@@ -2491,6 +2432,7 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
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,
@@ -2499,142 +2441,350 @@ void advance_sj_state(JOIN *join, table_map remaining_tables,
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 */
/*
- Use the strategy if
- * it is cheaper then what we've had, or
- * we haven't picked any other semi-join strategy yet
- In the second case, we pick this strategy unconditionally because
- comparing cost without semi-join duplicate removal with cost with
- duplicate removal is not an apples-to-apples comparison.
+ 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.
*/
- if (prefix_cost < *current_read_time || join->cur_dups_producing_tables)
- {
- pos->sj_strategy= SJ_OPT_MATERIALIZE_SCAN;
- *current_read_time= prefix_cost;
- *current_record_count= prefix_rec_count;
- join->cur_dups_producing_tables&= ~mat_nest->sj_inner_tables;
+ 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;
+}
- /* 5. Duplicate Weedout strategy handler */
+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;
+
/*
- Duplicate weedout can be applied after all ON-correlated and
- correlated
+ 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.
*/
- TABLE_LIST *nest;
- if ((nest= new_join_tab->emb_sj_nest))
- {
- if (!pos->dupsweedout_tables)
- pos->first_dupsweedout_table= idx;
-
- pos->dupsweedout_tables |= nest->sj_inner_tables |
- nest->nested_join->sj_depends_on |
- nest->nested_join->sj_corr_tables;
- }
-
- if (pos->dupsweedout_tables)
+ 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)))
{
- /* we're in the process of constructing a DuplicateWeedout range */
- TABLE_LIST *emb= new_join_tab->table->pos_in_table_list->embedding;
- /* and we've entered an inner side of an outer join*/
- if (emb && emb->on_expr)
- pos->dupsweedout_tables |= emb->nested_join->used_tables;
+ /* Start tracking potential FirstMatch range */
+ first_firstmatch_table= idx;
+ firstmatch_need_tables= sj_inner_tables;
+ first_firstmatch_rtbl= remaining_tables;
}
- if (pos->dupsweedout_tables &&
- !(remaining_tables &
- ~new_join_tab->table->map & pos->dupsweedout_tables))
+ if (in_firstmatch_prefix())
{
- /*
- Ok, reached a state where we could put a dups weedout point.
- Walk back and calculate
- - the join cost (this is needed as the accumulated cost may assume
- some other duplicate elimination method)
- - extra fanout that will be removed by duplicate elimination
- - duplicate elimination cost
- There are two cases:
- 1. We have other strategy/ies to remove all of the duplicates.
- 2. We don't.
-
- We need to calculate the cost in case #2 also because we need to make
- choice between this join order and others.
- */
- uint first_tab= pos->first_dupsweedout_table;
- double dups_cost;
- double prefix_rec_count;
- double sj_inner_fanout= 1.0;
- double sj_outer_fanout= 1.0;
- uint temptable_rec_size;
- if (first_tab == join->const_tables)
+ if (outer_corr_tables & first_firstmatch_rtbl)
{
- prefix_rec_count= 1.0;
- temptable_rec_size= 0;
- dups_cost= 0.0;
+ /*
+ 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
{
- 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 */
+ /* Record that we need all of this semi-join's inner tables, too */
+ firstmatch_need_tables|= sj_inner_tables;
}
-
- table_map dups_removed_fanout= 0;
- for (uint j= pos->first_dupsweedout_table; j <= idx; j++)
+
+ if (in_firstmatch_prefix() &&
+ !(firstmatch_need_tables & remaining_tables))
{
- POSITION *p= join->positions + j;
- dups_cost += p->read_time;
- if (p->table->emb_sj_nest)
+ /*
+ Got a complete FirstMatch range. Calculate correct costs and fanout
+ */
+
+ if (idx == first_firstmatch_table &&
+ optimizer_flag(join->thd, OPTIMIZER_SWITCH_SEMIJOIN_WITH_CACHE))
{
- sj_inner_fanout *= p->records_read;
- dups_removed_fanout |= p->table->table->map;
+ /*
+ 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
{
- sj_outer_fanout *= p->records_read;
- temptable_rec_size += p->table->table->file->ref_length;
+ 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;
}
+ }
+ }
+ return FALSE;
+}
- /*
- 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);
+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;
+}
+
- 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;
+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.
- /*
- Use the strategy if
- * it is cheaper then what we've had, or
- * we haven't picked any other semi-join strategy yet
- The second part is necessary because this strategy is the last one
- to consider (it needs "the most" tables in the prefix) and we can't
- leave duplicate-producing tables not handled by any strategy.
- */
- if (dups_cost < *current_read_time || join->cur_dups_producing_tables)
+ 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)
{
- pos->sj_strategy= SJ_OPT_DUPS_WEEDOUT;
- *current_read_time= dups_cost;
- *current_record_count= prefix_rec_count * sj_outer_fanout;
- join->cur_dups_producing_tables &= ~dups_removed_fanout;
+ 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;
}
@@ -2831,11 +2981,11 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
}
else if (pos->sj_strategy == SJ_OPT_MATERIALIZE_SCAN)
{
- POSITION *first_inner= join->best_positions + pos->sjm_scan_last_inner;
+ 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->sjm_scan_last_inner - sjm->tables + 1;
+ first= pos->sjmat_picker.sjm_scan_last_inner - sjm->tables + 1;
memcpy(join->best_positions + first,
sjm->positions, sizeof(POSITION) * sjm->tables);
join->best_positions[first].sj_strategy= SJ_OPT_MATERIALIZE_SCAN;
@@ -2873,7 +3023,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
if (pos->sj_strategy == SJ_OPT_FIRST_MATCH)
{
- first= pos->first_firstmatch_table;
+ 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
@@ -2906,7 +3056,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
if (pos->sj_strategy == SJ_OPT_LOOSE_SCAN)
{
- first= pos->first_loosescan_table;
+ 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:
@@ -2945,7 +3095,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
Duplicate Weedout starting at pos->first_dupsweedout_table, ending at
this table.
*/
- first= pos->first_dupsweedout_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;
}
@@ -2961,7 +3111,6 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
if (tablenr != first)
pos->sj_strategy= SJ_OPT_NONE;
remaining_tables |= s->table->map;
- //s->sj_strategy= pos->sj_strategy;
join->join_tab[first].sj_strategy= join->best_positions[first].sj_strategy;
join->join_tab[first].n_sj_tables= join->best_positions[first].n_sj_tables;
}
@@ -3028,6 +3177,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
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);
@@ -3337,12 +3487,8 @@ static bool is_cond_sj_in_equality(Item *item)
SYNOPSIS
- create_duplicate_weedout_tmp_table()
+ create_sj_weedout_tmp_table()
thd Thread handle
- uniq_tuple_length_arg Length of the table's column
- sjtbl Update sjtbl->[start_]recinfo values which
- will be needed if we'll need to convert the
- created temptable from HEAP to MyISAM/Maria.
DESCRIPTION
Create a temporary table to weed out duplicate rowid combinations. The
@@ -3367,9 +3513,8 @@ static bool is_cond_sj_in_equality(Item *item)
NULL on error
*/
-TABLE *create_duplicate_weedout_tmp_table(THD *thd,
- uint uniq_tuple_length_arg,
- SJ_TMP_TABLE *sjtbl)
+bool
+SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
{
MEM_ROOT *mem_root_save, own_root;
TABLE *table;
@@ -3382,15 +3527,17 @@ TABLE *create_duplicate_weedout_tmp_table(THD *thd,
uchar *group_buff;
uchar *bitmaps;
uint *blob_field;
- ENGINE_COLUMNDEF *recinfo, *start_recinfo;
bool using_unique_constraint=FALSE;
bool use_packed_rows= FALSE;
Field *field, *key_field;
uint null_pack_length, null_count;
uchar *null_flags;
uchar *pos;
- DBUG_ENTER("create_duplicate_weedout_tmp_table");
- DBUG_ASSERT(!sjtbl->is_degenerate);
+ 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
*/
@@ -3432,7 +3579,7 @@ TABLE *create_duplicate_weedout_tmp_table(THD *thd,
{
if (temp_pool_slot != MY_BIT_NONE)
bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
- DBUG_RETURN(NULL);
+ DBUG_RETURN(TRUE);
}
strmov(tmpname,path);
@@ -3636,20 +3783,19 @@ TABLE *create_duplicate_weedout_tmp_table(THD *thd,
if (create_internal_tmp_table(table, keyinfo, start_recinfo, &recinfo, 0, 0))
goto err;
}
- sjtbl->start_recinfo= start_recinfo;
- sjtbl->recinfo= recinfo;
if (open_tmp_table(table))
goto err;
thd->mem_root= mem_root_save;
- DBUG_RETURN(table);
+ 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(NULL); /* purecov: inspected */
+ DBUG_RETURN(TRUE); /* purecov: inspected */
}
@@ -3657,25 +3803,25 @@ err:
SemiJoinDuplicateElimination: Reset the temporary table
*/
-int do_sj_reset(SJ_TMP_TABLE *sj_tbl)
+int SJ_TMP_TABLE::sj_weedout_delete_rows()
{
- DBUG_ENTER("do_sj_reset");
- if (sj_tbl->tmp_table)
+ DBUG_ENTER("SJ_TMP_TABLE::sj_weedout_delete_rows");
+ if (tmp_table)
{
- int rc= sj_tbl->tmp_table->file->ha_delete_all_rows();
+ int rc= tmp_table->file->ha_delete_all_rows();
DBUG_RETURN(rc);
}
- sj_tbl->have_degenerate_row= FALSE;
+ have_degenerate_row= FALSE;
DBUG_RETURN(0);
}
+
/*
SemiJoinDuplicateElimination: Weed out duplicate row combinations
SYNPOSIS
- do_sj_dups_weedout()
+ sj_weedout_check_row()
thd Thread handle
- sjtbl Duplicate weedout table
DESCRIPTION
Try storing current record combination of outer tables (i.e. their
@@ -3688,47 +3834,47 @@ int do_sj_reset(SJ_TMP_TABLE *sj_tbl)
0 The row combination is not a duplicate (continue)
*/
-int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl)
+int SJ_TMP_TABLE::sj_weedout_check_row(THD *thd)
{
int error;
- SJ_TMP_TABLE::TAB *tab= sjtbl->tabs;
- SJ_TMP_TABLE::TAB *tab_end= sjtbl->tabs_end;
+ SJ_TMP_TABLE::TAB *tab= tabs;
+ SJ_TMP_TABLE::TAB *tab_end= tabs_end;
uchar *ptr;
uchar *nulls_ptr;
- DBUG_ENTER("do_sj_dups_weedout");
+ DBUG_ENTER("SJ_TMP_TABLE::sj_weedout_check_row");
- if (sjtbl->is_degenerate)
+ if (is_degenerate)
{
- if (sjtbl->have_degenerate_row)
+ if (have_degenerate_row)
DBUG_RETURN(1);
- sjtbl->have_degenerate_row= TRUE;
+ have_degenerate_row= TRUE;
DBUG_RETURN(0);
}
- ptr= sjtbl->tmp_table->record[0] + 1;
+ ptr= tmp_table->record[0] + 1;
/* Put the the rowids tuple into table->record[0]: */
// 1. Store the length
- if (((Field_varstring*)(sjtbl->tmp_table->field[0]))->length_bytes == 1)
+ if (((Field_varstring*)(tmp_table->field[0]))->length_bytes == 1)
{
- *ptr= (uchar)(sjtbl->rowid_len + sjtbl->null_bytes);
+ *ptr= (uchar)(rowid_len + null_bytes);
ptr++;
}
else
{
- int2store(ptr, sjtbl->rowid_len + sjtbl->null_bytes);
+ int2store(ptr, rowid_len + null_bytes);
ptr += 2;
}
nulls_ptr= ptr;
// 2. Zero the null bytes
- if (sjtbl->null_bytes)
+ if (null_bytes)
{
- bzero(ptr, sjtbl->null_bytes);
- ptr += sjtbl->null_bytes;
+ bzero(ptr, null_bytes);
+ ptr += null_bytes;
}
// 3. Put the rowids
@@ -3748,21 +3894,91 @@ int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl)
}
}
- error= sjtbl->tmp_table->file->ha_write_tmp_row(sjtbl->tmp_table->record[0]);
+ 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 (!sjtbl->tmp_table->file->is_fatal_error(error, HA_CHECK_DUP))
+ if (!tmp_table->file->is_fatal_error(error, HA_CHECK_DUP))
DBUG_RETURN(1); /* Duplicate */
- if (create_internal_tmp_table_from_heap(thd, sjtbl->tmp_table,
- sjtbl->start_recinfo,
- &sjtbl->recinfo, error, 1))
+ 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.
@@ -3863,9 +4079,9 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
uint no_jbuf_after)
{
uint i;
- THD *thd= join->thd;
DBUG_ENTER("setup_semijoin_dups_elimination");
-
+
+
POSITION *pos= join->best_positions + join->const_tables;
for (i= join->const_tables ; i < join->top_join_tab_count; )
{
@@ -3888,8 +4104,8 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
/* Calculate key length */
keylen= 0;
- keyno= pos->loosescan_key;
- for (uint kp=0; kp < pos->loosescan_parts; kp++)
+ 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_len= keylen;
@@ -3906,6 +4122,7 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
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++)
{
@@ -3925,74 +4142,21 @@ int setup_semijoin_dups_elimination(JOIN *join, ulonglong options,
{
/* Looks like we'll be using join buffer */
first_table= join->const_tables;
- break;
- }
- }
-
- SJ_TMP_TABLE::TAB sjtabs[MAX_TABLES];
- SJ_TMP_TABLE::TAB *last_tab= sjtabs;
- uint jt_rowid_offset= 0; // # tuple bytes are already occupied (w/o NULL bytes)
- uint jt_null_bits= 0; // # null bits in tuple bytes
- /*
- Walk through the range and remember
- - tables that need their rowids to be put into temptable
- - the last outer table
- */
- for (JOIN_TAB *j=join->join_tab + first_table;
- j < join->join_tab + i + pos->n_sj_tables; j++)
- {
- if (sj_table_is_included(join, j))
- {
- last_tab->join_tab= j;
- last_tab->rowid_offset= jt_rowid_offset;
- jt_rowid_offset += j->table->file->ref_length;
- if (j->table->maybe_null)
- {
- last_tab->null_byte= jt_null_bits / 8;
- last_tab->null_bit= jt_null_bits++;
+ /*
+ 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();
}
- last_tab++;
- j->table->prepare_for_position();
- j->keep_current_rowid= TRUE;
+ break;
}
}
- 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;
- sjtbl->tmp_table=
- create_duplicate_weedout_tmp_table(thd,
- sjtbl->rowid_len +
- sjtbl->null_bytes,
- sjtbl);
- join->sj_tmp_tables.push_back(sjtbl->tmp_table);
- }
- else
- {
- /*
- This is a special case where the entire subquery predicate does
- not depend on anything at all, ie this is
- WHERE const IN (uncorrelated select)
- */
- if (!(sjtbl= (SJ_TMP_TABLE*)thd->alloc(sizeof(SJ_TMP_TABLE))))
- DBUG_RETURN(TRUE); /* purecov: inspected */
- sjtbl->tmp_table= NULL;
- sjtbl->is_degenerate= TRUE;
- sjtbl->have_degenerate_row= FALSE;
- }
- join->join_tab[first_table].flush_weedout_table= sjtbl;
- join->join_tab[i + pos->n_sj_tables - 1].check_weed_out_table= sjtbl;
-
+ 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;
@@ -4074,6 +4238,8 @@ int clear_sj_tmp_tables(JOIN *join)
{
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;
@@ -4460,6 +4626,234 @@ enum_nested_loop_state join_tab_execution_startup(JOIN_TAB *tab)
}
+/*
+ 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->variables.option_bits | 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.
@@ -4502,6 +4896,13 @@ 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;
@@ -4761,8 +5162,16 @@ bool JOIN::choose_tableless_subquery_plan()
NULL.
*/
}
-
- if (subs_predicate->is_in_predicate())
+
+ /*
+ 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;
diff --git a/sql/opt_subselect.h b/sql/opt_subselect.h
index 08af798948d..c211fc67c84 100644
--- a/sql/opt_subselect.h
+++ b/sql/opt_subselect.h
@@ -10,6 +10,8 @@ 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,
@@ -40,7 +42,6 @@ ulonglong get_bound_sj_equalities(TABLE_LIST *sj_nest,
class Loose_scan_opt
{
-public:
/* All methods must check this before doing anything else */
bool try_loosescan;
@@ -71,6 +72,7 @@ public:
uint best_max_loose_keypart;
+public:
Loose_scan_opt():
try_loosescan(FALSE),
bound_sj_equalities(0),
@@ -263,8 +265,8 @@ public:
{
pos->records_read= best_loose_scan_records;
pos->key= best_loose_scan_start_key;
- pos->loosescan_key= best_loose_scan_key;
- pos->loosescan_parts= best_max_loose_keypart + 1;
+ pos->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 ?
@@ -277,8 +279,7 @@ public:
};
-void advance_sj_state(JOIN *join, const table_map remaining_tables,
- const JOIN_TAB *new_join_tab, uint idx,
+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,
@@ -289,10 +290,6 @@ 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);
-TABLE *create_duplicate_weedout_tmp_table(THD *thd, uint uniq_tuple_length_arg,
- SJ_TMP_TABLE *sjtbl);
-int do_sj_reset(SJ_TMP_TABLE *sj_tbl);
-int do_sj_dups_weedout(THD *thd, SJ_TMP_TABLE *sjtbl);
/*
Temporary table used by semi-join DuplicateElimination strategy
@@ -359,8 +356,11 @@ public:
ENGINE_COLUMNDEF *start_recinfo;
ENGINE_COLUMNDEF *recinfo;
- /* Pointer to next table (next->start_idx > this->end_idx) */
- SJ_TMP_TABLE *next;
+ 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,
diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 5962e7de706..cda35895a3d 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2011 Oracle and/or its affiliates.
- Copyright (c) 2010, 2011 Monty Program Ab
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ 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
@@ -301,7 +301,8 @@ int opt_sum_query(THD *thd,
is_exact_count= FALSE;
count= 1; // ensure count != 0
}
- else if (tl->is_materialized_derived())
+ else if (tl->is_materialized_derived() ||
+ tl->jtbm_subselect)
{
/*
Can't remove a derived table as it's number of rows is just an
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 7c8a520879f..028afd7899e 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/password.c b/sql/password.c
index a7e599d4777..f4ff3156bec 100644
--- a/sql/password.c
+++ b/sql/password.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/protocol.cc b/sql/protocol.cc
index eb9c3e34dbf..63b945f7078 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -1,5 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2011, Monty Program Ab
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+ 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
diff --git a/sql/records.cc b/sql/records.cc
index 1e74e6d7f30..5050064926b 100644
--- a/sql/records.cc
+++ b/sql/records.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index e355be185db..abc22a00695 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2001, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc
index dfa5ef95e67..3aa3a6a212c 100644
--- a/sql/rpl_injector.cc
+++ b/sql/rpl_injector.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h
index 54623577e0b..5875290fa02 100644
--- a/sql/rpl_mi.h
+++ b/sql/rpl_mi.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_record.cc b/sql/rpl_record.cc
index c893dc52587..d51e5a5ba4c 100644
--- a/sql/rpl_record.cc
+++ b/sql/rpl_record.cc
@@ -1,4 +1,6 @@
-/* Copyright (c) 2007, 2010, Oracle and/or its affiliates.
+/*
+ Copyright (c) 2007, 2010, Oracle and/or its affiliates.
+ 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
diff --git a/sql/rpl_record.h b/sql/rpl_record.h
index c857c07c33b..efe2a1da72c 100644
--- a/sql/rpl_record.h
+++ b/sql/rpl_record.h
@@ -1,4 +1,6 @@
-/* Copyright (c) 2007, 2010, Oracle and/or its affiliates.
+/*
+ Copyright (c) 2007, 2010, Oracle and/or its affiliates.
+ 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
diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index 2e5202d7cb6..299c032d02a 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h
index 8ff70dff825..6048fe07ecc 100644
--- a/sql/rpl_rli.h
+++ b/sql/rpl_rli.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc
index 4ab4542dd13..71fa5c8909c 100644
--- a/sql/rpl_utility.cc
+++ b/sql/rpl_utility.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h
index eebef266754..1f5577d8b8b 100644
--- a/sql/rpl_utility.h
+++ b/sql/rpl_utility.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 895facee6e9..8e2f90b9bfd 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2002, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009, 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
diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt
index 3d5d2eb9af5..0153c3f90b0 100644
--- a/sql/share/errmsg-utf8.txt
+++ b/sql/share/errmsg-utf8.txt
@@ -6558,3 +6558,4 @@ ER_CONNECTION_KILLED 70100
eng "Connection was killed"
ER_INTERNAL_ERROR
eng "Internal error: '%-.192s'"
+
diff --git a/sql/slave.cc b/sql/slave.cc
index 91ddf7bf171..ff371b270b7 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009-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
@@ -637,7 +637,7 @@ terminate_slave_thread(THD *thd,
while (*slave_running) // Should always be true
{
- int error;
+ int error __attribute__((unused));
DBUG_PRINT("loop", ("killing slave thread"));
mysql_mutex_lock(&thd->LOCK_thd_data);
diff --git a/sql/slave.h b/sql/slave.h
index 7bee83af744..e519a9fc3fa 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sp.cc b/sql/sp.cc
index 31cbe13a96e..29195234a5a 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index e82f1b92312..10304247611 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1027,12 +1027,23 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
/*
Allocate additional space at the end of the new query string for the
query_cache_send_result_to_client function.
+
+ The query buffer layout is:
+ buffer :==
+ <statement> The input statement(s)
+ '\0' Terminating null char
+ <length> Length of following current database name 2
+ <db_name> Name of current database
+ <flags> Flags struct
*/
- buf_len= qbuf.length() + thd->db_length + 1 + 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;
+ *ptr= 0;
+ int2store(ptr+1, thd->db_length);
}
else
DBUG_RETURN(TRUE);
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 96e119f23bc..c79b5dfbd0b 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -1,5 +1,6 @@
/* -*- C++ -*- */
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/spatial.h b/sql/spatial.h
index bea9ade9598..0d0560656f0 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -100,6 +101,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)
{
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index e4aa41b30ab..92747066121 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -8387,14 +8387,22 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
if (pkt_len < MIN_HANDSHAKE_SIZE)
return packet_error;
+ /*
+ Protocol buffer is guaranteed to always end with \0. (see my_net_read())
+ As the code below depends on this, lets check that.
+ */
+ DBUG_ASSERT(net->read_pos[pkt_len] == 0);
+
if (mpvio->connect_errors)
reset_host_errors(thd->main_security_ctx.ip);
ulong client_capabilities= uint2korr(net->read_pos);
if (client_capabilities & CLIENT_PROTOCOL_41)
{
- client_capabilities|= ((ulonglong) uint2korr(net->read_pos + 2)) << 16;
- thd->max_client_packet_length= uint4korr(net->read_pos + 4);
+ if (pkt_len < 32)
+ return packet_error;
+ client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
+ thd->max_client_packet_length= uint4korr(net->read_pos+4);
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
if (thd_init_client_charset(thd, (uint) net->read_pos[8]))
return packet_error;
@@ -8403,8 +8411,10 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
}
else
{
- thd->max_client_packet_length= uint3korr(net->read_pos + 2);
- end= (char*) net->read_pos + 5;
+ if (pkt_len < 5)
+ return packet_error;
+ thd->max_client_packet_length= uint3korr(net->read_pos+2);
+ end= (char*) net->read_pos+5;
}
/* Disable those bits which are not supported by the client. */
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index 8a2f475b6f2..f01e279333d 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -334,6 +334,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
strxmov(table_name, db, ".", table->table_name, NullS);
+ thd->open_options|= extra_open_options;
table->lock_type= lock_type;
/*
To make code safe for re-execution we need to reset type of MDL
@@ -369,8 +370,6 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
lex->sql_command == SQLCOM_ANALYZE ||
lex->sql_command == SQLCOM_OPTIMIZE)
thd->prepare_derived_at_open= TRUE;
-
- thd->open_options|= extra_open_options;
if (!thd->locked_tables_mode && repair_table_use_frm)
{
/*
@@ -403,11 +402,11 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
open_error= open_and_lock_tables(thd, table, TRUE, 0);
}
- thd->open_options&= ~extra_open_options;
thd->prepare_derived_at_open= FALSE;
table->next_global= save_next_global;
table->next_local= save_next_local;
+ thd->open_options&= ~extra_open_options;
/*
If open_and_lock_tables() failed, close_thread_tables() will close
@@ -620,9 +619,17 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
if (check_old_types == HA_ADMIN_NEEDS_ALTER ||
check_for_upgrade == HA_ADMIN_NEEDS_ALTER)
{
+ /* 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;
goto send_result;
}
+ if (check_old_types || check_for_upgrade)
+ {
+ /* If repair is not implemented for the engine, run ALTER TABLE */
+ need_repair_or_alter= 1;
+ }
}
DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index d99337bd210..31e13882515 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index e7abef13c75..2dc1893068f 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -918,6 +918,7 @@ void intern_close_table(TABLE *table)
delete table->triggers;
if (table->file) // Not true if placeholder
(void) closefrm(table, 1); // close file
+ table->alias.free();
DBUG_VOID_RETURN;
}
@@ -8160,7 +8161,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context,
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 ???*/
+ my_error(ER_TOO_MANY_TABLES,MYF(0), static_cast<int>(MAX_TABLES)); /* psergey-todo: WHY ER_TOO_MANY_TABLES ???*/
DBUG_RETURN(1);
}
DBUG_ASSERT(item == table_list->jtbm_subselect->optimizer);
@@ -8704,9 +8705,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.
@@ -8769,10 +8772,12 @@ fill_record(THD * thd, List<Item> &fields, List<Item> &values,
goto err;
}
}
- thd->abort_on_warning= abort_on_warning_saved;
+ 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);
diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc
index 5ddff949ce3..664590c34ac 100644
--- a/sql/sql_binlog.cc
+++ b/sql/sql_binlog.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2005, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index 6bc1d5204b6..7212f6996eb 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -467,6 +468,7 @@ static void make_base_query(String *new_query,
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))
{
/*
@@ -545,8 +547,11 @@ insert_space:
}
if (buffer == last_space)
buffer--; // Remove the last space
- *buffer= 0;
+ *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);
}
@@ -1482,7 +1487,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
/* Key is query + database + flag */
if (thd->db_length)
{
- memcpy((char*) (query + query_length + 1), thd->db, thd->db_length);
+ 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));
}
@@ -1490,8 +1496,8 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
{
DBUG_PRINT("qcache", ("No active database"));
}
- tot_length= query_length + thd->db_length + 1 +
- 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
@@ -1654,7 +1660,7 @@ Query_cache::send_result_to_client(THD *thd, char *org_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;
+ const char *sql, *sql_end, *found_brace= 0;
DBUG_ENTER("Query_cache::send_result_to_client");
/*
@@ -1728,9 +1734,16 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
case '\n':
case '\t':
case ' ':
- case '(': // To handle (select a from t1) union (select a from t1);
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;
}
@@ -1755,7 +1768,28 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
DBUG_PRINT("qcache", ("The statement has a SQL_NO_CACHE directive"));
goto err;
}
+ {
+ /*
+ We have allocated buffer space (in alloc_query) to hold the
+ SQL statement(s) + the current database name + a flags struct.
+ If the database name has changed during execution, which might
+ happen if there are multiple statements, we need to make
+ sure the new current database has a name with the same length
+ as the previous one.
+ */
+ size_t db_len= uint2korr(sql_end+1);
+ if (thd->db_length != db_len)
+ {
+ /*
+ We should probably reallocate the buffer in this case,
+ but for now we just leave it uncached
+ */
+ DBUG_PRINT("qcache",
+ ("Current database has changed since start of query"));
+ goto err;
+ }
+ }
/*
Try to obtain an exclusive lock on the query cache. If the cache is
disabled or if a full cache flush is in progress, the attempt to
@@ -1772,8 +1806,11 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
Query_cache_block *query_block;
if (thd->variables.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_FLAGS_SIZE);
+ thd->db_length + 1 + QUERY_CACHE_DB_LENGTH_SIZE +
+ QUERY_CACHE_FLAGS_SIZE);
sql= thd->base_query.ptr();
query_length= thd->base_query.length();
}
@@ -1783,12 +1820,15 @@ Query_cache::send_result_to_client(THD *thd, char *org_sql, uint query_length)
thd->base_query.set(sql, query_length, system_charset_info);
}
- tot_length= query_length + thd->db_length + 1 + 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((char*) (sql+query_length+1), 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
{
@@ -1910,7 +1950,7 @@ 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
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index 87b861b34f8..9d713d012f5 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -545,6 +545,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_abort(A) query_cache.abort(A)
#define query_cache_end_of_result(A) query_cache.end_of_result(A)
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index cc58a131f00..5230663809d 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ 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
@@ -1080,27 +1081,10 @@ MYSQL_ERROR* THD::raise_condition(uint sql_errno,
{
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 (lex->current_select &&
- lex->current_select->no_error && !is_fatal_error)
+ if (! stmt_da->is_error())
{
- DBUG_PRINT("error",
- ("Error converted to warning: current_select: no_error %d "
- "fatal_error: %d",
- (lex->current_select ?
- lex->current_select->no_error : 0),
- (int) is_fatal_error));
- }
- else
- {
- if (! stmt_da->is_error())
- {
- set_row_count_func(-1);
- stmt_da->set_error_status(this, sql_errno, msg, sqlstate);
- }
+ set_row_count_func(-1);
+ stmt_da->set_error_status(this, sql_errno, msg, sqlstate);
}
}
@@ -2870,7 +2854,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)
@@ -4250,16 +4235,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;
}
}
/***************************************************************************
diff --git a/sql/sql_class.h b/sql/sql_class.h
index dd1617d7546..b39f0506ee1 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
2009-2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 3c88b7a054d..265ef1e6e9f 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -1,5 +1,6 @@
/*
- Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2007, 2011, Oracle and/or its affiliates.
+ 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
@@ -870,7 +871,6 @@ bool init_new_connection_handler_thread()
return 0;
}
-#ifndef EMBEDDED_LIBRARY
/*
Perform handshake, authorize client and update thd ACL variables.
@@ -883,6 +883,7 @@ bool init_new_connection_handler_thread()
1 error
*/
+#ifndef EMBEDDED_LIBRARY
static int check_connection(THD *thd)
{
uint connect_errors= 0;
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 7350618adc0..c50cded7470 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 2301dae5fdf..052616f6965 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index efce55cc18a..f48724236d4 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -131,8 +132,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())
{
@@ -359,16 +358,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;
@@ -673,7 +665,7 @@ multi_delete::initialize_tables(JOIN *join)
for (JOIN_TAB *tab= first_linear_tab(join, WITH_CONST_TABLES);
tab;
- tab= next_linear_tab(join, tab, WITH_BUSH_ROOTS))
+ tab= next_linear_tab(join, tab, WITHOUT_BUSH_ROOTS))
{
if (tab->table->map & tables_to_delete_from)
{
@@ -758,7 +750,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;
@@ -909,11 +901,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);
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index dee2f01fb15..01125bdb97b 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index ca0e695b3fe..c352272e95c 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 70c66d6cf29..7d33f3e4c07 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -78,6 +78,8 @@
#include "sql_audit.h"
#include "sql_derived.h" // mysql_handle_derived
+#include "debug_sync.h"
+
#ifndef EMBEDDED_LIBRARY
static bool delayed_get_table(THD *thd, MDL_request *grl_protection_request,
TABLE_LIST *table_list);
@@ -1595,6 +1597,8 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
error= HA_ERR_FOUND_DUPP_KEY; /* Database can't find key */
goto err;
}
+ DEBUG_SYNC(thd, "write_row_replace");
+
/* Read all columns for the row we are going to replace */
table->use_all_columns();
/*
@@ -1685,11 +1689,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 &&
@@ -1764,11 +1769,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;
@@ -1784,6 +1790,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
}
else if ((error=table->file->ha_write_row(table->record[0])))
{
+ DEBUG_SYNC(thd, "write_row_noreplace");
if (!info->ignore ||
table->file->is_fatal_error(error, HA_CHECK_DUP))
goto err;
@@ -1807,9 +1814,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:
@@ -3268,8 +3272,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));
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index 76d01b076f0..3600bbbb65f 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -2368,7 +2368,7 @@ enum_nested_loop_state JOIN_CACHE::generate_full_extensions(uchar *rec_ptr)
int res= 0;
if (!join_tab->check_weed_out_table ||
- !(res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table)))
+ !(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);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index a9d542756fb..723329379d0 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1796,7 +1797,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;
}
@@ -1865,10 +1866,10 @@ void st_select_lex::init_query()
exclude_from_table_unique_test= no_wrap_view_item= FALSE;
nest_level= 0;
link_next= 0;
- m_non_agg_field_used= false;
- m_agg_func_used= false;
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;
}
void st_select_lex::init_select()
@@ -1901,10 +1902,10 @@ void st_select_lex::init_select()
non_agg_fields.empty();
cond_value= having_value= Item::COND_UNDEF;
inner_refs_list.empty();
- m_non_agg_field_used= false;
- m_agg_func_used= false;
insert_tables= 0;
merged_into= 0;
+ m_non_agg_field_used= false;
+ m_agg_func_used= false;
}
/*
@@ -3762,20 +3763,58 @@ void st_select_lex::set_explain_type()
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;
+ }
- type= ((&master_unit()->thd->lex->select_lex == this) ?
- (is_primary ? "PRIMARY" : "SIMPLE"):
- ((this == first) ?
- ((linkage == DERIVED_TABLE_TYPE) ?
- "DERIVED" :
- ((is_uncacheable & UNCACHEABLE_DEPENDENT) ?
- "DEPENDENT SUBQUERY" :
- (is_uncacheable ? "UNCACHEABLE SUBQUERY" :
- "SUBQUERY"))) :
- ((is_uncacheable & UNCACHEABLE_DEPENDENT) ?
- "DEPENDENT UNION":
- is_uncacheable ? "UNCACHEABLE UNION":
- "UNION")));
+ 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;
}
@@ -3841,12 +3880,12 @@ bool st_select_lex::save_leaf_tables(THD *thd)
{
if (leaf_tables_exec.push_back(table))
return 1;
- table->tablenr_exec= table->table->tablenr;
- table->map_exec= table->table->map;
+ 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->maybe_null;
+ table->maybe_null_exec= table->table? table->table->maybe_null: 0;
}
if (arena)
thd->restore_active_arena(arena, &backup);
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index c776dfc5a8c..d4e94c8d2d8 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -529,7 +530,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 ()
{
diff --git a/sql/sql_list.h b/sql/sql_list.h
index 894edc4516d..7bd72cba359 100644
--- a/sql/sql_list.h
+++ b/sql/sql_list.h
@@ -1,6 +1,7 @@
#ifndef INCLUDES_MYSQL_SQL_LIST_H
#define INCLUDES_MYSQL_SQL_LIST_H
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index bc926118723..aab9ea76499 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -190,7 +190,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
*/
char *tdb= thd->db ? thd->db : db; // Result is never null
ulong skip_lines= ex->skip_lines;
- bool transactional_table;
+ bool transactional_table __attribute__((unused));
DBUG_ENTER("mysql_load");
/*
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ee2998e6e5e..4d98313c5ae 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1,5 +1,6 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2011 Monty Program Ab
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ 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
@@ -548,8 +549,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);
thd->set_query_and_id(query, length, thd->charset(), next_query_id());
+ int2store(query + length + 1, 0); // No db in bootstrap
DBUG_PRINT("query",("%-.4096s",thd->query()));
#if defined(ENABLED_PROFILING)
thd->profiling.start_new_query();
@@ -1240,6 +1243,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
case COM_REFRESH:
{
int not_used;
+
+ /*
+ Initialize thd->lex since it's used in many base functions, such as
+ open_tables(). Otherwise, it remains unitialized and may cause crash
+ during execution of COM_REFRESH.
+ */
+ lex_start(thd);
+
status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]);
ulong options= (ulong) (uchar) packet[0];
if (trans_commit_implicit(thd))
@@ -1674,13 +1685,30 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length)
pos--;
packet_length--;
}
- /* We must allocate some extra memory for query cache */
+ /* We must allocate some extra memory for query cache
+
+ The query buffer layout is:
+ buffer :==
+ <statement> The input statement(s)
+ '\0' Terminating null char (1 byte)
+ <length> Length of following current database name (size_t)
+ <db_name> Name of current database
+ <flags> Flags struct
+ */
if (! (query= (char*) thd->memdup_w_gap(packet,
packet_length,
1 + thd->db_length +
+ QUERY_CACHE_DB_LENGTH_SIZE +
QUERY_CACHE_FLAGS_SIZE)))
return TRUE;
query[packet_length]= '\0';
+ /*
+ Space to hold the name of the current database is allocated. We
+ also store this length, in case current database is changed during
+ execution. We might need to reallocate the 'query' buffer
+ */
+ int2store(query + packet_length + 1, thd->db_length);
+
thd->set_query(query, packet_length);
/* Reclaim some memory */
@@ -7562,8 +7590,8 @@ bool parse_sql(THD *thd,
*/
DBUG_ASSERT(!mysql_parse_status ||
- (mysql_parse_status && thd->is_error()) ||
- (mysql_parse_status && thd->get_internal_handler()));
+ thd->is_error() ||
+ thd->get_internal_handler());
/* Reset parser state. */
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index d2c15ae46d8..cc11d859903 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -1,7 +1,8 @@
#ifndef SQL_PARTITION_INCLUDED
#define SQL_PARTITION_INCLUDED
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h
index f0b706bc322..aee04de7be4 100644
--- a/sql/sql_plugin.h
+++ b/sql/sql_plugin.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2005, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index f35d336fd65..f5a2f409dfc 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1,5 +1,5 @@
/* Copyright (c) 2002, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009-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
@@ -2515,9 +2515,6 @@ void reinit_stmt_before_use(THD *thd, LEX *lex)
for (order= sl->order_list.first; order; order= order->next)
order->item= &order->item_ptr;
sl->handle_derived(lex, DT_REINIT);
-
- /* clear the no_error flag for INSERT/UPDATE IGNORE */
- sl->no_error= FALSE;
}
{
SELECT_LEX_UNIT *unit= sl->master_unit();
diff --git a/sql/sql_priv.h b/sql/sql_priv.h
index 412686a49c9..b9017f1e5ab 100644
--- a/sql/sql_priv.h
+++ b/sql/sql_priv.h
@@ -197,15 +197,19 @@
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN | \
+ OPTIMIZER_SWITCH_DERIVED_MERGE | \
+ OPTIMIZER_SWITCH_DERIVED_WITH_KEYS | \
OPTIMIZER_SWITCH_TABLE_ELIMINATION | \
OPTIMIZER_SWITCH_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_SUBQUERY_CACHE | \
OPTIMIZER_SWITCH_SEMIJOIN | \
OPTIMIZER_SWITCH_FIRSTMATCH | \
OPTIMIZER_SWITCH_LOOSE_SCAN )
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index fe593dbae88..e743e474747 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -1,4 +1,6 @@
-/* Copyright (c) 2007, 2010, Oracle and/or its affiliates.
+/*
+ Copyright (c) 2007, 2010, Oracle and/or its affiliates.
+ 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
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 6cc08e64d86..6b0d1e980f9 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 4152c07da37..5bfb19f6828 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -1,5 +1,6 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009-2011, Monty Program Ab
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ 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
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 07daaa2bd5c..f22510bb2b7 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -80,7 +80,7 @@ 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 create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
- table_map used_tables);
+ 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,
@@ -106,7 +106,7 @@ C_MODE_END
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 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,
@@ -451,6 +451,73 @@ 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,
@@ -547,6 +614,22 @@ JOIN::prepare(Item ***rref_pointer_array,
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,
@@ -589,6 +672,9 @@ JOIN::prepare(Item ***rref_pointer_array,
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;
@@ -824,58 +910,6 @@ err:
}
-void
-inject_jtbm_conds(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("inject_jtbm_conds");
-
-
- while ((table= li++))
- {
- Item_in_subselect *item;
-
- if ((item= table->jtbm_subselect))
- {
- Item_in_subselect *subq_pred= item;
- double rows;
- double read_time;
-
- //DBUG_ASSERT(subq_pred->test_set_strategy(SUBS_MATERIALIZATION));
- subq_pred->optimize(&rows, &read_time);
-
- subq_pred->jtbm_read_time= read_time;
- subq_pred->jtbm_record_count=rows;
- subq_pred->is_jtbm_merged= TRUE;
-
- subselect_hash_sj_engine *hash_sj_engine=
- ((subselect_hash_sj_engine*)item->engine);
-
-
- //repeat of convert_subq_to_jtbm:
- table->table= hash_sj_engine->tmp_table;
- table->table->pos_in_table_list= table;
-
- setup_table_map(table->table, table, table->jtbm_table_no);
-
- 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);
- //parent_join->select_lex->where= parent_join->conds;
- }
-
- if ((nested_join= table->nested_join))
- {
- inject_jtbm_conds(join, &nested_join->join_list, join_where);
- }
- }
- DBUG_VOID_RETURN;
-}
-
/**
global select optimisation.
@@ -947,9 +981,6 @@ JOIN::optimize()
select_limit= unit->select_limit_cnt;
if (having || (select_options & OPTION_FOUND_ROWS))
select_limit= HA_POS_ERROR;
- // 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)
@@ -1003,7 +1034,8 @@ JOIN::optimize()
thd->restore_active_arena(arena, &backup);
}
- inject_jtbm_conds(this, join_list, &conds);
+ if (setup_jtbm_semi_joins(this, join_list, &conds))
+ DBUG_RETURN(1);
conds= optimize_cond(this, conds, join_list, &cond_value, &cond_equal);
@@ -1450,7 +1482,10 @@ JOIN::optimize()
DBUG_RETURN(1);
}
if (old_group_list && !group_list)
+ {
+ DBUG_ASSERT(group);
select_distinct= 0;
+ }
}
if (!group_list && group)
{
@@ -1458,6 +1493,7 @@ JOIN::optimize()
simple_order=1;
select_distinct= 0; // No need in distinct for 1 row
group_optimized_away= 1;
+ implicit_grouping= TRUE;
}
calc_group_buffer(this, group_list);
@@ -1484,7 +1520,7 @@ JOIN::optimize()
}
// 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);
@@ -1501,22 +1537,7 @@ JOIN::optimize()
}
}
- /*
- 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.
- */
- need_tmp= ((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));
+ need_tmp= test_if_need_tmp_table();
/*
If the hint FORCE INDEX FOR ORDER BY/GROUP BY is used for the table
@@ -1655,6 +1676,7 @@ JOIN::optimize()
}
error= 0;
+
DBUG_RETURN(0);
setup_subq_exit:
@@ -2903,7 +2925,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
if (!(join= new JOIN(thd, fields, select_options, result)))
DBUG_RETURN(TRUE);
thd_proc_info(thd, "init");
- thd->lex->used_tables=0; // Updated by setup_fields
+ thd->lex->used_tables=0;
if ((err= join->prepare(rref_pointer_array, tables, wild_num,
conds, og_num, order, group, having, proc_param,
select_lex, unit)))
@@ -3048,6 +3070,14 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
table->pos_in_table_list= tables;
error= tables->fetch_number_of_rows();
+ DBUG_EXECUTE_IF("bug11747970_raise_error",
+ {
+ if (!error)
+ {
+ my_error(ER_UNKNOWN_ERROR, MYF(0));
+ goto error;
+ }
+ });
if (error)
{
table->file->print_error(error, MYF(0));
@@ -3132,6 +3162,14 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
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;
@@ -3376,7 +3414,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
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,
@@ -4982,7 +5020,7 @@ 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].loosescan_key= MAX_KEY; /* Not a LooseScan */
join->positions[idx].sj_strategy= SJ_OPT_NONE;
join->positions[idx].use_join_buffer= FALSE;
@@ -5080,6 +5118,8 @@ best_access_path(JOIN *join,
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");
@@ -5476,7 +5516,9 @@ best_access_path(JOIN *join,
(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 &&
+ 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)
@@ -5632,7 +5674,7 @@ best_access_path(JOIN *join,
pos->key= best_key;
pos->table= s;
pos->ref_depend_map= best_ref_depends_map;
- pos->loosescan_key= MAX_KEY;
+ pos->loosescan_picker.loosescan_key= MAX_KEY;
pos->use_join_buffer= best_uses_jbuf;
loose_scan_opt.save_to_position(s, loose_scan_pos);
@@ -5938,22 +5980,22 @@ optimize_straight_join(JOIN *join, table_map join_tables)
/* compute the cost of the new plan extended with 's' */
record_count*= join->positions[idx].records_read;
- read_time+= join->positions[idx].read_time;
- advance_sj_state(join, join_tables, s, idx, &record_count, &read_time,
+ 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->record_count= record_count;
- join->best_read= read_time;
+ join->best_read= read_time - 0.001;
}
@@ -6121,7 +6163,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;
@@ -6229,7 +6272,7 @@ void JOIN::get_partial_cost_and_fanout(int end_tab_idx,
if (tab->records_read && (cur_table_map & filter_map))
{
record_count *= tab->records_read;
- read_time += tab->read_time;
+ read_time += tab->read_time + record_count / (double) TIME_FOR_COMPARE;
if (tab->emb_sj_nest)
sj_inner_fanout *= tab->records_read;
}
@@ -6453,21 +6496,19 @@ best_extension_by_limited_search(JOIN *join,
/* Compute the cost of extending the plan with 's' */
current_record_count= record_count * position->records_read;
- current_read_time= read_time + position->read_time;
+ current_read_time=read_time + position->read_time +
+ current_record_count / (double) TIME_FOR_COMPARE;
- advance_sj_state(join, remaining_tables, s, idx, &current_record_count,
+ 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);
@@ -6526,13 +6567,12 @@ 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));
@@ -6612,7 +6652,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
*/
double current_record_count=record_count*records;
double current_read_time=read_time+best;
- advance_sj_state(join, rest_tables, s, idx, &current_record_count,
+ advance_sj_state(join, rest_tables, idx, &current_record_count,
&current_read_time, &loose_scan_pos);
if (best_record_count > current_record_count ||
@@ -7112,7 +7152,7 @@ static Item * const null_ptr= NULL;
TRUE Out of memory
*/
-static bool
+bool
get_best_combination(JOIN *join)
{
uint tablenr;
@@ -7129,6 +7169,7 @@ get_best_combination(JOIN *join)
DBUG_RETURN(TRUE);
join->full_join=0;
+ join->hash_join= FALSE;
used_tables= OUTER_REF_TABLE_BIT; // Outer row is already read
@@ -7190,13 +7231,6 @@ get_best_combination(JOIN *join)
*j= *join->best_positions[tablenr].table;
-#if 0
-/* SJ-Materialization is represented with join tab ranges */
- if (j->sj_strategy == SJ_OPT_MATERIALIZE ||
- j->sj_strategy == SJ_OPT_MATERIALIZE)
- j->sj_strategy= SJ_OPT_NONE;
-#endif
-
j->bush_root_tab= sjm_nest_root;
form=join->table[tablenr]=j->table;
@@ -7215,16 +7249,27 @@ get_best_combination(JOIN *join)
if (j->type == JT_SYSTEM)
goto loop_end;
- if ( !(keyuse= join->best_positions[tablenr].key) ||
- (join->best_positions[tablenr].sj_strategy == SJ_OPT_LOOSE_SCAN))
+ if ( !(keyuse= join->best_positions[tablenr].key))
{
j->type=JT_ALL;
- j->index= join->best_positions[tablenr].loosescan_key;
if (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
@@ -7285,10 +7330,26 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
do
{
- if (!(~used_tables & keyuse->used_tables) &&
- (first_keyuse || keyuse->keypart != (keyuse-1)->keypart))
- key_parts++;
- first_keyuse= FALSE;
+ if (!(~used_tables & 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))
+ break;
+ }
+ if (curr == keyuse)
+ key_parts++;
+ }
+ }
keyuse++;
} while (keyuse->table == table && keyuse->is_for_hash_join());
if (!key_parts)
@@ -7313,15 +7374,31 @@ static bool create_hj_key_for_table(JOIN *join, JOIN_TAB *join_tab,
keyuse= org_keyuse;
do
{
- if (!(~used_tables & keyuse->used_tables) &&
- (first_keyuse || keyuse->keypart != (keyuse-1)->keypart))
- {
- Field *field= table->field[keyuse->keypart];
- uint fieldnr= keyuse->keypart+1;
- table->create_key_part_by_field(keyinfo, key_part_info, field, fieldnr);
- first_keyuse= FALSE;
- key_part_info++;
+ if (!(~used_tables & 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))
+ {
+ 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());
@@ -7359,7 +7436,8 @@ 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)
+ KEYUSE *org_keyuse, bool allow_full_scan,
+ table_map used_tables)
{
uint keyparts, length, key;
TABLE *table;
@@ -7404,8 +7482,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
{
if (are_tables_local(j, keyuse->val->used_tables()))
{
- if ((is_hash_join_key_no(key) &&
- (keyparts == 0 || keyuse->keypart != (keyuse-1)->keypart)) ||
+ 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)))
{
@@ -7418,6 +7495,14 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
keyuse++;
} while (keyuse->table == table && keyuse->key == key);
} /* 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);
+ }
/* set up fieldref */
j->ref.key_parts= keyparts;
@@ -7459,6 +7544,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
for (i=0 ; i < keyparts ; keyuse++,i++)
{
while (((~used_tables) & keyuse->used_tables) ||
+ keyuse->keypart == NO_KEYPART ||
(keyuse->keypart !=
(is_hash_join_key_no(key) ?
keyinfo->key_part[i].field->field_index : i)) ||
@@ -8042,14 +8128,33 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
DBUG_RETURN(1); // Impossible const condition
}
- COND *outer_ref_cond= make_cond_for_table(thd, cond,
- OUTER_REF_TABLE_BIT,
- OUTER_REF_TABLE_BIT,
- -1, FALSE, FALSE);
- if (outer_ref_cond)
- {
- add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond);
- join->outer_ref_cond= outer_ref_cond;
+ if (join->table_count != join->const_tables)
+ {
+ 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)
+ {
+ add_cond_and_fix(thd, &outer_ref_cond, join->outer_ref_cond);
+ join->outer_ref_cond= outer_ref_cond;
+ }
+ }
+ else
+ {
+ 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;
+ }
}
}
}
@@ -8441,9 +8546,39 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
COND *tmp_cond= make_cond_for_table(thd, on_expr, used_tables2,
current_map, /*(tab - first_tab)*/ -1,
FALSE, FALSE);
- if (tab == first_inner_tab && tab->on_precond)
+ 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)
+ 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 ?
@@ -8872,8 +9007,7 @@ void revise_cache_usage(JOIN_TAB *join_tab)
first_inner= join_tab->first_sj_inner_tab;
for (tab= join_tab-1; tab >= first_inner; tab--)
{
- if (tab->first_sj_inner_tab == first_inner)
- set_join_cache_denial(tab);
+ set_join_cache_denial(tab);
}
}
else set_join_cache_denial(join_tab);
@@ -9157,11 +9291,12 @@ uint check_join_cache_usage(JOIN_TAB *tab,
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)
+ 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->first_sj_inner_tab->use_join_cache || !(tab-1)->use_join_cache))
goto no_join_cache;
if (!prev_tab->use_join_cache)
{
@@ -9692,8 +9827,6 @@ bool error_if_full_join(JOIN *join)
{
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);
@@ -9734,9 +9867,22 @@ void JOIN_TAB::cleanup()
if (table->pos_in_table_list &&
table->pos_in_table_list->jtbm_subselect)
{
- end_read_record(&read_record);
- table->pos_in_table_list->jtbm_subselect->cleanup();
- table= NULL;
+ 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;
}
/*
@@ -12047,7 +12193,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();
}
@@ -12104,7 +12250,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)
@@ -12117,7 +12263,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.
@@ -14189,10 +14335,22 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
key_part_info->store_length= key_part_info->length;
if ((*reg_field)->real_maybe_null())
+ {
key_part_info->store_length+= HA_KEY_NULL_LENGTH;
- if ((*reg_field)->type() == MYSQL_TYPE_BLOB ||
- (*reg_field)->real_type() == MYSQL_TYPE_VARCHAR)
- key_part_info->store_length+= HA_KEY_BLOB_LENGTH;
+ 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;
@@ -14224,6 +14382,9 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
goto err;
}
+ // Make empty record so random data is not written to disk
+ empty_record(table);
+
thd->mem_root= mem_root_save;
DBUG_RETURN(table);
@@ -14718,6 +14879,7 @@ bool create_internal_tmp_table(TABLE *table, KEY *keyinfo,
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);
@@ -15041,15 +15203,14 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
{
/*
HAVING will be checked after processing aggregate functions,
- But WHERE should checkd here (we alredy have read tables).
- If there is join->exec_const_cond, and all tables are constant, then it
- is equivalent to join->conds. exec_const_cond is already checked in the
- beginning of JOIN::exec. If it is false, JOIN::exec returns zero
- result already there, therefore execution reaches this point only if
- exec_const_cond is TRUE. Since it is equvalent to join->conds, then
- join->conds is also TRUE.
+ 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->exec_const_cond || 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)
@@ -15375,10 +15536,12 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
int error;
enum_nested_loop_state rc= NESTED_LOOP_OK;
READ_RECORD *info= &join_tab->read_record;
-
- if (join_tab->flush_weedout_table)
+
+ for (SJ_TMP_TABLE *flush_dups_table= join_tab->flush_weedout_table;
+ flush_dups_table;
+ flush_dups_table= flush_dups_table->next_flush_table)
{
- do_sj_reset(join_tab->flush_weedout_table);
+ flush_dups_table->sj_weedout_delete_rows();
}
if (!join_tab->preread_init_done && join_tab->preread_init())
@@ -15427,7 +15590,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
join_tab->loosescan_match_tab->found_match)
{
KEY *key= join_tab->table->key_info + join_tab->index;
- key_copy(join_tab->loosescan_buf, info->record, key,
+ key_copy(join_tab->loosescan_buf, join_tab->table->record[0], key,
join_tab->loosescan_key_len);
skip_over= TRUE;
}
@@ -15603,7 +15766,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
if (join_tab->check_weed_out_table && found)
{
- int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
+ 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)
@@ -15730,7 +15893,7 @@ evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
*/
if (join_tab->check_weed_out_table)
{
- int res= do_sj_dups_weedout(join->thd, join_tab->check_weed_out_table);
+ 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)
@@ -15810,6 +15973,17 @@ join_read_const_table(JOIN_TAB *tab, POSITION *pos)
/* 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)))
@@ -17675,8 +17849,8 @@ find_field_in_item_list (Field *field, void *data)
while ((item= li++))
{
- if (item->type() == Item::FIELD_ITEM &&
- ((Item_field*) item)->field->eq(field))
+ if (item->real_item()->type() == Item::FIELD_ITEM &&
+ ((Item_field*) (item->real_item()))->field->eq(field))
{
part_found= 1;
break;
@@ -17810,7 +17984,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
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))
goto use_filesort;
@@ -20665,7 +20839,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
/* id */
item_list.push_back(new Item_uint((uint32)select_id));
/* select_type */
- const char* stype= printing_materialize_nest? "SUBQUERY" :
+ const char* stype= printing_materialize_nest? "MATERIALIZED" :
join->select_lex->type;
item_list.push_back(new Item_string(stype, strlen(stype), cs));
@@ -21062,7 +21236,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
extra.append(STRING_WITH_LEN("; LooseScan"));
}
- if (tab->flush_weedout_table)
+ 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"));
@@ -21370,11 +21544,29 @@ void TABLE_LIST::print(THD *thd, table_map eliminated_tables, String *str,
}
else if (jtbm_subselect)
{
- 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(')');
+ 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
{
@@ -22015,7 +22207,8 @@ test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
uint used_pk_parts= 0;
if (used_key_parts > used_index_parts)
used_pk_parts= used_key_parts-used_index_parts;
- rec_per_key= keyinfo->rec_per_key[used_key_parts-1];
+ rec_per_key= used_key_parts ?
+ keyinfo->rec_per_key[used_key_parts-1] : 1;
/* Take into account the selectivity of the used pk prefix */
if (used_pk_parts)
{
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 4b5e2903c1d..644828fa08c 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -2,7 +2,7 @@
#define SQL_SELECT_INCLUDED
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2010, 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
@@ -84,6 +84,8 @@ typedef struct keyuse_t {
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);
@@ -165,6 +167,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
@@ -278,7 +291,16 @@ typedef struct st_join_table {
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;
ulong used_fieldlength;
@@ -326,6 +348,8 @@ typedef struct st_join_table {
/* 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
@@ -370,7 +394,7 @@ typedef struct st_join_table {
POSITION::sj_strategy field. This field is set up by the
fix_semijoin_strategies_for_picked_join_order.
*/
- uint sj_strategy;
+ enum sj_strategy_enum sj_strategy;
uint n_sj_tables;
@@ -502,12 +526,221 @@ 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
{
+ /* 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
@@ -521,7 +754,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.
@@ -531,14 +767,13 @@ typedef struct st_position
/* If ref-based access is used: bitmap of tables this table depends on */
table_map ref_depend_map;
-
- bool use_join_buffer;
-
-
- /* These form a stack of partial join order costs and output sizes */
- COST_VECT prefix_cost;
- double prefix_record_count;
-
+
+ /*
+ 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.
@@ -551,7 +786,8 @@ typedef struct st_position
this applies to. The values of covered_preceding_positions->sj_strategy
must be ignored.
*/
- uint sj_strategy;
+ 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
@@ -559,67 +795,15 @@ typedef struct st_position
*/
uint n_sj_tables;
-/* LooseScan strategy members */
-
- /* The first (i.e. driving) table we're doing loose scan for */
- uint first_loosescan_table;
- /*
- Tables that need to be in the prefix before we can calculate the cost
- of using LooseScan strategy.
- */
- table_map loosescan_need_tables;
-
- /*
- keyno - Planning to do LooseScan on this key. If keyuse is NULL then
- this is a full index scan, otherwise this is a ref+loosescan
- scan (and keyno matches the KEUSE's)
- MAX_KEY - Not doing a LooseScan
- */
- uint loosescan_key; // final (one for strategy instance )
- uint loosescan_parts; /* Number of keyparts to be kept distinct */
-
-/* FirstMatch strategy */
- /*
- Index of the first inner table that we intend to handle with this
- strategy
- */
- uint first_firstmatch_table;
- /*
- Tables that were not in the join prefix when we've started considering
- FirstMatch strategy.
- */
- table_map first_firstmatch_rtbl;
- /*
- Tables that need to be in the prefix before we can calculate the cost
- of using FirstMatch strategy.
- */
- table_map firstmatch_need_tables;
-
- bool in_firstmatch_prefix() { return (first_firstmatch_table != MAX_TABLES); }
- void invalidate_firstmatch_prefix() { first_firstmatch_table= MAX_TABLES; }
-
-/* Duplicate Weedout strategy */
- /* The first table that the strategy will need to handle */
- uint first_dupsweedout_table;
- /*
- Tables that we will need to have in the prefix to do the weedout step
- (all inner and all outer that the involved semi-joins are correlated with)
- */
- table_map dupsweedout_tables;
-
-/* SJ-Materialization-Scan strategy */
- /* The last inner table (valid once we're after it) */
- uint sjm_scan_last_inner;
- /*
- Tables that we need to have in the prefix to calculate the correct cost.
- Basically, we need all inner tables and outer tables mentioned in the
- semi-join's ON expression so we can correctly account for fanout.
- */
- table_map sjm_scan_need_tables;
-
table_map prefix_dups_producing_tables;
-} POSITION;
+ 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
{
@@ -631,18 +815,6 @@ typedef struct st_rollup
} ROLLUP;
-#define SJ_OPT_NONE 0
-#define SJ_OPT_DUPS_WEEDOUT 1
-#define SJ_OPT_LOOSE_SCAN 2
-#define SJ_OPT_FIRST_MATCH 3
-#define SJ_OPT_MATERIALIZE 4
-#define SJ_OPT_MATERIALIZE_SCAN 5
-
-inline bool sj_is_materialize_strategy(uint strategy)
-{
- return strategy >= SJ_OPT_MATERIALIZE;
-}
-
class JOIN_TAB_RANGE: public Sql_alloc
{
public:
@@ -750,6 +922,7 @@ public:
*/
bool sort_and_group;
bool first_record,full_join, no_field_update;
+ bool hash_join;
bool do_send_rows;
table_map const_table_map;
/*
@@ -810,7 +983,7 @@ public:
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 *******/
/*
@@ -935,6 +1108,7 @@ public:
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;
@@ -1061,7 +1235,7 @@ public:
rollup.state= ROLLUP::STATE_NONE;
no_const_tables= FALSE;
- outer_ref_cond= 0;
+ outer_ref_cond= pseudo_bits_cond= NULL;
in_to_exists_where= NULL;
in_to_exists_having= NULL;
}
@@ -1151,6 +1325,25 @@ public:
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,
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index d098bca4776..d64c7a6df52 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -688,6 +688,21 @@ public:
};
+/*
+ Return CREATE command for table or view
+
+ @param thd Thread handler
+ @param table_list Table / view
+
+ @return
+ @retval 0 OK
+ @retval 1 Error
+
+ @notes
+ table_list->db and table_list->table_name are kept unchanged to
+ not cause problems with SP.
+*/
+
bool
mysqld_show_create(THD *thd, TABLE_LIST *table_list)
{
@@ -3442,8 +3457,8 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys,
LEX_STRING db_name, table_name;
TABLE_LIST *table_list;
bool result= true;
-
DBUG_ENTER("fill_schema_table_by_open");
+
/*
When a view is opened its structures are allocated on a permanent
statement arena and linked into the LEX tree for the current statement
@@ -4216,7 +4231,6 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
}
DEBUG_SYNC(thd, "before_open_in_get_all_tables");
-
if (fill_schema_table_by_open(thd, FALSE,
table, schema_table,
db_name, table_name,
diff --git a/sql/sql_string.cc b/sql/sql_string.cc
index 683511c3da4..c4f5f315b08 100644
--- a/sql/sql_string.cc
+++ b/sql/sql_string.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_string.h b/sql/sql_string.h
index e0f9af9615b..86af507918c 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -1,7 +1,9 @@
#ifndef SQL_STRING_INCLUDED
#define SQL_STRING_INCLUDED
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ 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
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index abd29ea6a02..349cc7f3045 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3431,7 +3431,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
}
if (!f_is_geom(sql_field->pack_flag))
{
- my_error(ER_SPATIAL_MUST_HAVE_GEOM_COL, MYF(0));
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
DBUG_RETURN(TRUE);
}
}
@@ -5873,7 +5873,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
TABLE *table_for_fast_alter_partition= NULL;
bool partition_changed= FALSE;
#endif
- bool need_lock_for_indexes= TRUE;
+ bool need_lock_for_indexes __attribute__((unused)) = TRUE;
KEY *key_info_buffer;
uint index_drop_count= 0;
uint *index_drop_buffer= NULL;
@@ -6287,7 +6287,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
need_copy_table= ALTER_TABLE_DATA_CHANGED;
else
{
- enum_alter_table_change_level need_copy_table_res;
+ enum_alter_table_change_level need_copy_table_res=ALTER_TABLE_METADATA_ONLY;
/* Check how much the tables differ. */
if (mysql_compare_tables(table, alter_info,
create_info, order_num,
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 0ecc43b512f..dacdaca3fa2 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2004, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2258,7 +2258,8 @@ void Table_triggers_list::mark_fields_used(trg_event_type event)
void Table_triggers_list::set_parse_error_message(char *error_message)
{
m_has_unparseable_trigger= true;
- strcpy(m_parse_error_message, error_message);
+ strnmov(m_parse_error_message, error_message,
+ sizeof(m_parse_error_message)-1);
}
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index 84637b79818..47b1d19ae54 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -2,7 +2,7 @@
#define SQL_TRIGGER_INCLUDED
/*
- Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2004, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 7eb0cd7ebf7..e41598f943c 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 9f24ed45842..584ebd904a8 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 94dffad822e..d39ec82aad1 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -847,7 +847,7 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view,
thd->variables.sql_mode|= sql_mode;
}
- DBUG_PRINT("info", ("View: %s", view_query.c_ptr_safe()));
+ DBUG_PRINT("info", ("View: %.*s", view_query.length(), view_query.ptr()));
/* fill structure */
view->source= thd->lex->create_view_select;
@@ -1283,6 +1283,37 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
if (!table->prelocking_placeholder &&
(old_lex->sql_command == SQLCOM_SELECT && old_lex->describe))
{
+ /*
+ The user we run EXPLAIN as (either the connected user who issued
+ the EXPLAIN statement, or the definer of a SUID stored routine
+ which contains the EXPLAIN) should have both SHOW_VIEW_ACL and
+ SELECT_ACL on the view being opened as well as on all underlying
+ views since EXPLAIN will disclose their structure. This user also
+ should have SELECT_ACL on all underlying tables of the view since
+ this EXPLAIN will disclose information about the number of rows in it.
+
+ To perform this privilege check we create auxiliary TABLE_LIST object
+ for the view in order a) to avoid trashing "table->grant" member for
+ original table list element, which contents can be important at later
+ stage for column-level privilege checking b) get TABLE_LIST object
+ with "security_ctx" member set to 0, i.e. forcing check_table_access()
+ to use active user's security context.
+
+ There is no need for creating similar copies of TABLE_LIST elements
+ for underlying tables since they just have been constructed and thus
+ have TABLE_LIST::security_ctx == 0 and fresh TABLE_LIST::grant member.
+
+ Finally at this point making sure we have SHOW_VIEW_ACL on the views
+ will suffice as we implicitly require SELECT_ACL anyway.
+ */
+
+ TABLE_LIST view_no_suid;
+ bzero(static_cast<void *>(&view_no_suid), sizeof(TABLE_LIST));
+ view_no_suid.db= table->db;
+ view_no_suid.table_name= table->table_name;
+
+ DBUG_ASSERT(view_tables == NULL || view_tables->security_ctx == NULL);
+
if (check_table_access(thd, SELECT_ACL, view_tables, FALSE,
UINT_MAX, TRUE) &&
check_table_access(thd, SHOW_VIEW_ACL, table, FALSE, UINT_MAX, TRUE))
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index c070f0ecf7c..eb53c8a00cb 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -3339,7 +3339,7 @@ static Sys_var_ulong Sys_join_cache_level(
"numbers are used for plain join buffers while even numbers are used "
"for linked buffers",
SESSION_VAR(join_cache_level), CMD_LINE(REQUIRED_ARG),
- VALID_RANGE(0, 8), DEFAULT(1), BLOCK_SIZE(1));
+ VALID_RANGE(0, 8), DEFAULT(2), BLOCK_SIZE(1));
static Sys_var_ulong Sys_mrr_buffer_size(
"mrr_buffer_size",
diff --git a/sql/table.cc b/sql/table.cc
index fc0ee45add9..53e5872bfe4 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2011, Oracle and/or its affiliates.
- Copyright (c) 2009-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
@@ -6327,6 +6327,8 @@ bool TABLE_LIST::init_derived(THD *thd, bool init_view)
int TABLE_LIST::fetch_number_of_rows()
{
int error= 0;
+ if (jtbm_subselect)
+ return 0;
if (is_materialized_derived() && !fill_me)
{
diff --git a/sql/table.h b/sql/table.h
index b22cdb6e76b..a327d625387 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -1598,6 +1598,26 @@ struct TABLE_LIST
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:
diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc
index ba534e52b99..cedcbefc26f 100644
--- a/sql/thr_malloc.cc
+++ b/sql/thr_malloc.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/tztime.cc b/sql/tztime.cc
index aa945687675..9fae9f3fedd 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2004, 2010, Oracle and/or its affiliates.
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
diff --git a/sql/udf_example.c b/sql/udf_example.c
index d68f49e1729..36a5eafb704 100644
--- a/sql/udf_example.c
+++ b/sql/udf_example.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/unireg.cc b/sql/unireg.cc
index b5faac3b797..c9b0f91d9f7 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/sql/unireg.h b/sql/unireg.h
index f1066dbccb8..50aaa103b34 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -1,7 +1,8 @@
#ifndef UNIREG_INCLUDED
#define UNIREG_INCLUDED
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/archive/archive_reader.c b/storage/archive/archive_reader.c
index eac70810e1c..1b15fa16ce4 100644
--- a/storage/archive/archive_reader.c
+++ b/storage/archive/archive_reader.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2007, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 3ccd1e83800..4008165865a 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2004, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index 719c7b10069..64fd7102e93 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2004, 2010, Oracle and/or its affiliates
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
diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc
index 8566b013851..5101d73d23c 100644
--- a/storage/example/ha_example.cc
+++ b/storage/example/ha_example.cc
@@ -1,4 +1,5 @@
-/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2004, 2010, Oracle and/or its affiliates
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
@@ -991,7 +992,6 @@ bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
uint table_changes)
{
ha_table_option_struct *param_old, *param_new;
- uint i;
DBUG_ENTER("ha_example::check_if_incompatible_data");
/*
This example shows how custom engine specific table and field
@@ -1021,7 +1021,8 @@ bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
param_new->boolparam != param_old->boolparam)
DBUG_RETURN(COMPATIBLE_DATA_NO);
- for (i= 0; i < table->s->fields; i++)
+#ifndef DBUG_OFF
+ for (uint i= 0; i < table->s->fields; i++)
{
ha_field_option_struct *f_old, *f_new;
f_old= table->s->field[i]->option_struct;
@@ -1041,6 +1042,7 @@ bool ha_example::check_if_incompatible_data(HA_CREATE_INFO *info,
else
DBUG_PRINT("info", ("old field %i did not changed", i));
}
+#endif
DBUG_RETURN(COMPATIBLE_DATA_YES);
}
diff --git a/storage/example/ha_example.h b/storage/example/ha_example.h
index 08af1922662..ca8ca5ff293 100644
--- a/storage/example/ha_example.h
+++ b/storage/example/ha_example.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2004, 2010, Oracle and/or its affiliates
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
diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc
index a7c1c9904bb..1091d88ffc8 100644
--- a/storage/federated/ha_federated.cc
+++ b/storage/federated/ha_federated.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2004, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1547,7 +1547,7 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table)
tmp_share.table_name_length, ident_quote_char);
if (!(share= (FEDERATED_SHARE *) memdup_root(&mem_root, (char*)&tmp_share, sizeof(*share))) ||
- !(share->select_query= (char*) strmake_root(&mem_root, query.ptr(), query.length() + 1)))
+ !(share->select_query= (char*) strmake_root(&mem_root, query.ptr(), query.length())))
goto error;
share->use_count= 0;
diff --git a/storage/federated/ha_federated.h b/storage/federated/ha_federated.h
index 796eabf2f2d..98b0efdbe2b 100644
--- a/storage/federated/ha_federated.h
+++ b/storage/federated/ha_federated.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2004, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/heap/ha_heap.cc b/storage/heap/ha_heap.cc
index cf18ee29ee1..305a8cae720 100644
--- a/storage/heap/ha_heap.cc
+++ b/storage/heap/ha_heap.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/heap/ha_heap.h b/storage/heap/ha_heap.h
index 4b4e0d44d99..c5b8a09b216 100644
--- a/storage/heap/ha_heap.h
+++ b/storage/heap/ha_heap.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ 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
diff --git a/storage/heap/hp_hash.c b/storage/heap/hp_hash.c
index 424b1de0869..e916224c4d5 100644
--- a/storage/heap/hp_hash.c
+++ b/storage/heap/hp_hash.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index f63ca20ef24..625721133fd 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -1895,7 +1895,7 @@ btr_cur_update_in_place(
was_delete_marked = rec_get_deleted_flag(
rec, page_is_comp(buf_block_get_frame(block)));
- is_hashed = block->is_hashed;
+ is_hashed = (block->index != NULL);
if (is_hashed) {
/* TO DO: Can we skip this if none of the fields
@@ -3542,16 +3542,11 @@ btr_record_not_null_field_in_rec(
}
for (i = 0; i < n_unique; i++) {
- ulint rec_len;
-
- rec_get_nth_field_offs(offsets, i, &rec_len);
-
- if (rec_len != UNIV_SQL_NULL) {
- n_not_null[i]++;
- } else {
- /* Break if we hit the first NULL value */
+ if (rec_offs_nth_sql_null(offsets, i)) {
break;
}
+
+ n_not_null[i]++;
}
}
@@ -3694,8 +3689,7 @@ btr_estimate_number_of_different_key_vals(
if (n_not_null) {
btr_record_not_null_field_in_rec(
- n_cols, offsets_next_rec,
- n_not_null);
+ n_cols, offsets_next_rec, n_not_null);
}
total_external_size
diff --git a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c
index cbb0d21a7ed..57d9752649f 100644
--- a/storage/innobase/btr/btr0pcur.c
+++ b/storage/innobase/btr/btr0pcur.c
@@ -247,6 +247,8 @@ btr_pcur_restore_position_func(
cursor->rel_pos == BTR_PCUR_BEFORE_FIRST_IN_TREE,
index, latch_mode, btr_pcur_get_btr_cur(cursor), mtr);
+ cursor->latch_mode = latch_mode;
+ cursor->pos_state = BTR_PCUR_IS_POSITIONED;
cursor->block_when_stored = btr_pcur_get_block(cursor);
return(FALSE);
diff --git a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
index 7070420425c..ddc94064da9 100644
--- a/storage/innobase/btr/btr0sea.c
+++ b/storage/innobase/btr/btr0sea.c
@@ -44,12 +44,8 @@ Created 2/17/1996 Heikki Tuuri
#include "ha0ha.h"
/** Flag: has the search system been enabled?
-Protected by btr_search_latch and btr_search_enabled_mutex. */
+Protected by btr_search_latch. */
UNIV_INTERN char btr_search_enabled = TRUE;
-UNIV_INTERN ibool btr_search_fully_disabled = FALSE;
-
-/** Mutex protecting btr_search_enabled */
-static mutex_t btr_search_enabled_mutex;
#ifdef UNIV_PFS_MUTEX
/* Key to register btr_search_enabled_mutex with performance schema */
@@ -180,8 +176,6 @@ btr_search_sys_create(
rw_lock_create(btr_search_latch_key, &btr_search_latch,
SYNC_SEARCH_SYS);
- mutex_create(btr_search_enabled_mutex_key,
- &btr_search_enabled_mutex, SYNC_SEARCH_SYS_CONF);
btr_search_sys = mem_alloc(sizeof(btr_search_sys_t));
@@ -211,27 +205,37 @@ void
btr_search_disable(void)
/*====================*/
{
- mutex_enter(&btr_search_enabled_mutex);
+ dict_table_t* table;
+
+ mutex_enter(&dict_sys->mutex);
rw_lock_x_lock(&btr_search_latch);
- /* Disable access to hash index, also tell ha_insert_for_fold()
- stop adding new nodes to hash index, but still allow updating
- existing nodes */
btr_search_enabled = FALSE;
- /* Clear all block->is_hashed flags and remove all entries
- from btr_search_sys->hash_index. */
- buf_pool_drop_hash_index();
+ /* Clear the index->search_info->ref_count of every index in
+ the data dictionary cache. */
+ for (table = UT_LIST_GET_FIRST(dict_sys->table_LRU); table;
+ table = UT_LIST_GET_NEXT(table_LRU, table)) {
+
+ dict_index_t* index;
- /* hash index has been cleaned up, disallow any operation to
- the hash index */
- btr_search_fully_disabled = TRUE;
+ for (index = dict_table_get_first_index(table); index;
+ index = dict_table_get_next_index(index)) {
+
+ index->search_info->ref_count = 0;
+ }
+ }
- /* btr_search_enabled_mutex should guarantee this. */
- ut_ad(!btr_search_enabled);
+ mutex_exit(&dict_sys->mutex);
+
+ /* Set all block->index = NULL. */
+ buf_pool_clear_hash_index();
+
+ /* Clear the adaptive hash index. */
+ hash_table_clear(btr_search_sys->hash_index);
+ mem_heap_empty(btr_search_sys->hash_index->heap);
rw_lock_x_unlock(&btr_search_latch);
- mutex_exit(&btr_search_enabled_mutex);
}
/********************************************************************//**
@@ -241,14 +245,11 @@ void
btr_search_enable(void)
/*====================*/
{
- mutex_enter(&btr_search_enabled_mutex);
rw_lock_x_lock(&btr_search_latch);
btr_search_enabled = TRUE;
- btr_search_fully_disabled = FALSE;
rw_lock_x_unlock(&btr_search_latch);
- mutex_exit(&btr_search_enabled_mutex);
}
/*****************************************************************//**
@@ -471,7 +472,7 @@ btr_search_update_block_hash_info(
&& (block->n_bytes == info->n_bytes)
&& (block->left_side == info->left_side)) {
- if ((block->is_hashed)
+ if ((block->index)
&& (block->curr_n_fields == info->n_fields)
&& (block->curr_n_bytes == info->n_bytes)
&& (block->curr_left_side == info->left_side)) {
@@ -500,7 +501,7 @@ btr_search_update_block_hash_info(
/ BTR_SEARCH_PAGE_BUILD_LIMIT)
&& (info->n_hash_potential >= BTR_SEARCH_BUILD_LIMIT)) {
- if ((!block->is_hashed)
+ if ((!block->index)
|| (block->n_hash_helps
> 2 * page_get_n_recs(block->frame))
|| (block->n_fields != block->curr_n_fields)
@@ -532,9 +533,9 @@ btr_search_update_hash_ref(
buf_block_t* block, /*!< in: buffer block where cursor positioned */
btr_cur_t* cursor) /*!< in: cursor */
{
+ dict_index_t* index;
ulint fold;
- rec_t* rec;
- index_id_t index_id;
+ const rec_t* rec;
ut_ad(cursor->flag == BTR_CUR_HASH_FAIL);
#ifdef UNIV_SYNC_DEBUG
@@ -545,13 +546,15 @@ btr_search_update_hash_ref(
ut_ad(page_align(btr_cur_get_rec(cursor))
== buf_block_get_frame(block));
- if (!block->is_hashed) {
+ index = block->index;
+
+ if (!index) {
return;
}
- ut_a(block->index == cursor->index);
- ut_a(!dict_index_is_ibuf(cursor->index));
+ ut_a(index == cursor->index);
+ ut_a(!dict_index_is_ibuf(index));
if ((info->n_hash_potential > 0)
&& (block->curr_n_fields == info->n_fields)
@@ -568,12 +571,11 @@ btr_search_update_hash_ref(
return;
}
- index_id = cursor->index->id;
fold = rec_fold(rec,
- rec_get_offsets(rec, cursor->index, offsets_,
+ rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap),
block->curr_n_fields,
- block->curr_n_bytes, index_id);
+ block->curr_n_bytes, index->id);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -837,7 +839,7 @@ btr_search_guess_on_hash(
{
buf_pool_t* buf_pool;
buf_block_t* block;
- rec_t* rec;
+ const rec_t* rec;
ulint fold;
index_id_t index_id;
#ifdef notdefined
@@ -923,7 +925,7 @@ btr_search_guess_on_hash(
ut_ad(page_rec_is_user_rec(rec));
- btr_cur_position(index, rec, block, cursor);
+ btr_cur_position(index, (rec_t*) rec, block, cursor);
/* Check the validity of the guess within the page */
@@ -1053,15 +1055,16 @@ btr_search_drop_page_hash_index(
retry:
rw_lock_s_lock(&btr_search_latch);
- page = block->frame;
+ index = block->index;
- if (UNIV_LIKELY(!block->is_hashed)) {
+ if (UNIV_LIKELY(!index)) {
rw_lock_s_unlock(&btr_search_latch);
return;
}
+ ut_a(!dict_index_is_ibuf(index));
table = btr_search_sys->hash_index;
#ifdef UNIV_SYNC_DEBUG
@@ -1072,8 +1075,6 @@ retry:
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
- index = block->index;
- ut_a(!dict_index_is_ibuf(index));
/* NOTE: The fields of block must not be accessed after
releasing btr_search_latch, as the index page might only
@@ -1083,6 +1084,7 @@ retry:
ut_a(n_fields + n_bytes > 0);
+ page = block->frame;
n_recs = page_get_n_recs(page);
/* Calculate and cache fold values into an array for fast deletion
@@ -1131,7 +1133,7 @@ next_rec:
rw_lock_x_lock(&btr_search_latch);
- if (UNIV_UNLIKELY(!block->is_hashed)) {
+ if (UNIV_UNLIKELY(!block->index)) {
/* Someone else has meanwhile dropped the hash index */
goto cleanup;
@@ -1159,9 +1161,8 @@ next_rec:
ut_a(index->search_info->ref_count > 0);
index->search_info->ref_count--;
- block->is_hashed = FALSE;
block->index = NULL;
-
+
cleanup:
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
if (UNIV_UNLIKELY(block->n_pointers)) {
@@ -1187,8 +1188,8 @@ cleanup:
}
/********************************************************************//**
-Drops a page hash index when a page is freed from a fseg to the file system.
-Drops possible hash index if the page happens to be in the buffer pool. */
+Drops a possible page hash index when a page is evicted from the buffer pool
+or freed in a file segment. */
UNIV_INTERN
void
btr_search_drop_page_hash_when_freed(
@@ -1201,28 +1202,19 @@ btr_search_drop_page_hash_when_freed(
buf_block_t* block;
mtr_t mtr;
- if (!buf_page_peek_if_search_hashed(space, page_no)) {
-
- return;
- }
-
mtr_start(&mtr);
- /* We assume that if the caller has a latch on the page, then the
- caller has already dropped the hash index for the page, and we never
- get here. Therefore we can acquire the s-latch to the page without
- having to fear a deadlock. */
+ /* If the caller has a latch on the page, then the caller must
+ have a x-latch on the page and it must have already dropped
+ the hash index for the page. Because of the x-latch that we
+ are possibly holding, we cannot s-latch the page, but must
+ (recursively) x-latch it, even though we are only reading. */
- block = buf_page_get_gen(space, zip_size, page_no, RW_S_LATCH, NULL,
+ block = buf_page_get_gen(space, zip_size, page_no, RW_X_LATCH, NULL,
BUF_PEEK_IF_IN_POOL, __FILE__, __LINE__,
&mtr);
- /* Because the buffer pool mutex was released by
- buf_page_peek_if_search_hashed(), it is possible that the
- block was removed from the buffer pool by another thread
- before buf_page_get_gen() got a chance to acquire the buffer
- pool mutex again. Thus, we must check for a NULL return. */
- if (UNIV_LIKELY(block != NULL)) {
+ if (block && block->index) {
buf_block_dbg_add_level(block, SYNC_TREE_NODE_FROM_HASH);
@@ -1254,7 +1246,6 @@ btr_search_build_page_hash_index(
rec_t* next_rec;
ulint fold;
ulint next_fold;
- index_id_t index_id;
ulint n_cached;
ulint n_recs;
ulint* folds;
@@ -1268,9 +1259,6 @@ btr_search_build_page_hash_index(
ut_ad(index);
ut_a(!dict_index_is_ibuf(index));
- table = btr_search_sys->hash_index;
- page = buf_block_get_frame(block);
-
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
@@ -1279,9 +1267,17 @@ btr_search_build_page_hash_index(
rw_lock_s_lock(&btr_search_latch);
- if (block->is_hashed && ((block->curr_n_fields != n_fields)
- || (block->curr_n_bytes != n_bytes)
- || (block->curr_left_side != left_side))) {
+ if (!btr_search_enabled) {
+ rw_lock_s_unlock(&btr_search_latch);
+ return;
+ }
+
+ table = btr_search_sys->hash_index;
+ page = buf_block_get_frame(block);
+
+ if (block->index && ((block->curr_n_fields != n_fields)
+ || (block->curr_n_bytes != n_bytes)
+ || (block->curr_left_side != left_side))) {
rw_lock_s_unlock(&btr_search_latch);
@@ -1318,7 +1314,7 @@ btr_search_build_page_hash_index(
n_cached = 0;
- index_id = btr_page_get_index_id(page);
+ ut_a(index->id == btr_page_get_index_id(page));
rec = page_rec_get_next(page_get_infimum_rec(page));
@@ -1333,7 +1329,7 @@ btr_search_build_page_hash_index(
}
}
- fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
+ fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id);
if (left_side) {
@@ -1360,7 +1356,7 @@ btr_search_build_page_hash_index(
offsets = rec_get_offsets(next_rec, index, offsets,
n_fields + (n_bytes > 0), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
- n_bytes, index_id);
+ n_bytes, index->id);
if (fold != next_fold) {
/* Insert an entry into the hash index */
@@ -1385,13 +1381,13 @@ btr_search_build_page_hash_index(
rw_lock_x_lock(&btr_search_latch);
- if (UNIV_UNLIKELY(btr_search_fully_disabled)) {
+ if (UNIV_UNLIKELY(!btr_search_enabled)) {
goto exit_func;
}
- if (block->is_hashed && ((block->curr_n_fields != n_fields)
- || (block->curr_n_bytes != n_bytes)
- || (block->curr_left_side != left_side))) {
+ if (block->index && ((block->curr_n_fields != n_fields)
+ || (block->curr_n_bytes != n_bytes)
+ || (block->curr_left_side != left_side))) {
goto exit_func;
}
@@ -1400,11 +1396,10 @@ btr_search_build_page_hash_index(
rebuild hash index for a page that is already hashed, we
have to take care not to increment the counter in that
case. */
- if (!block->is_hashed) {
+ if (!block->index) {
index->search_info->ref_count++;
}
- block->is_hashed = TRUE;
block->n_hash_helps = 0;
block->curr_n_fields = n_fields;
@@ -1452,14 +1447,15 @@ btr_search_move_or_delete_hash_entries(
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
ut_ad(rw_lock_own(&(new_block->lock), RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
- ut_a(!new_block->is_hashed || new_block->index == index);
- ut_a(!block->is_hashed || block->index == index);
- ut_a(!(new_block->is_hashed || block->is_hashed)
- || !dict_index_is_ibuf(index));
rw_lock_s_lock(&btr_search_latch);
- if (new_block->is_hashed) {
+ ut_a(!new_block->index || new_block->index == index);
+ ut_a(!block->index || block->index == index);
+ ut_a(!(new_block->index || block->index)
+ || !dict_index_is_ibuf(index));
+
+ if (new_block->index) {
rw_lock_s_unlock(&btr_search_latch);
@@ -1468,7 +1464,7 @@ btr_search_move_or_delete_hash_entries(
return;
}
- if (block->is_hashed) {
+ if (block->index) {
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
@@ -1505,42 +1501,48 @@ btr_search_update_hash_on_delete(
{
hash_table_t* table;
buf_block_t* block;
- rec_t* rec;
+ const rec_t* rec;
ulint fold;
- index_id_t index_id;
+ dict_index_t* index;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
mem_heap_t* heap = NULL;
rec_offs_init(offsets_);
- rec = btr_cur_get_rec(cursor);
-
block = btr_cur_get_block(cursor);
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
- if (!block->is_hashed) {
+ index = block->index;
+
+ if (!index) {
return;
}
- ut_a(block->index == cursor->index);
+ ut_a(index == cursor->index);
ut_a(block->curr_n_fields + block->curr_n_bytes > 0);
- ut_a(!dict_index_is_ibuf(cursor->index));
+ ut_a(!dict_index_is_ibuf(index));
table = btr_search_sys->hash_index;
- index_id = cursor->index->id;
- fold = rec_fold(rec, rec_get_offsets(rec, cursor->index, offsets_,
+ rec = btr_cur_get_rec(cursor);
+
+ fold = rec_fold(rec, rec_get_offsets(rec, index, offsets_,
ULINT_UNDEFINED, &heap),
- block->curr_n_fields, block->curr_n_bytes, index_id);
+ block->curr_n_fields, block->curr_n_bytes, index->id);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
+
rw_lock_x_lock(&btr_search_latch);
- ha_search_and_delete_if_found(table, fold, rec);
+ if (block->index) {
+ ut_a(block->index == index);
+
+ ha_search_and_delete_if_found(table, fold, rec);
+ }
rw_lock_x_unlock(&btr_search_latch);
}
@@ -1558,6 +1560,7 @@ btr_search_update_hash_node_on_insert(
{
hash_table_t* table;
buf_block_t* block;
+ dict_index_t* index;
rec_t* rec;
rec = btr_cur_get_rec(cursor);
@@ -1568,16 +1571,25 @@ btr_search_update_hash_node_on_insert(
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
- if (!block->is_hashed) {
+ index = block->index;
+
+ if (!index) {
return;
}
- ut_a(block->index == cursor->index);
- ut_a(!dict_index_is_ibuf(cursor->index));
+ ut_a(cursor->index == index);
+ ut_a(!dict_index_is_ibuf(index));
rw_lock_x_lock(&btr_search_latch);
+ if (!block->index) {
+
+ goto func_exit;
+ }
+
+ ut_a(block->index == index);
+
if ((cursor->flag == BTR_CUR_HASH)
&& (cursor->n_fields == block->curr_n_fields)
&& (cursor->n_bytes == block->curr_n_bytes)
@@ -1588,6 +1600,7 @@ btr_search_update_hash_node_on_insert(
ha_search_and_update_if_found(table, cursor->fold, rec,
block, page_rec_get_next(rec));
+func_exit:
rw_lock_x_unlock(&btr_search_latch);
} else {
rw_lock_x_unlock(&btr_search_latch);
@@ -1609,10 +1622,10 @@ btr_search_update_hash_on_insert(
{
hash_table_t* table;
buf_block_t* block;
+ dict_index_t* index;
rec_t* rec;
rec_t* ins_rec;
rec_t* next_rec;
- index_id_t index_id;
ulint fold;
ulint ins_fold;
ulint next_fold = 0; /* remove warning (??? bug ???) */
@@ -1637,15 +1650,15 @@ btr_search_update_hash_on_insert(
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
- if (!block->is_hashed) {
+ index = block->index;
+
+ if (!index) {
return;
}
- ut_a(block->index == cursor->index);
- ut_a(!dict_index_is_ibuf(cursor->index));
-
- index_id = cursor->index->id;
+ ut_a(index == cursor->index);
+ ut_a(!dict_index_is_ibuf(index));
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
@@ -1654,21 +1667,21 @@ btr_search_update_hash_on_insert(
ins_rec = page_rec_get_next(rec);
next_rec = page_rec_get_next(ins_rec);
- offsets = rec_get_offsets(ins_rec, cursor->index, offsets,
+ offsets = rec_get_offsets(ins_rec, index, offsets,
ULINT_UNDEFINED, &heap);
- ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index_id);
+ ins_fold = rec_fold(ins_rec, offsets, n_fields, n_bytes, index->id);
if (!page_rec_is_supremum(next_rec)) {
- offsets = rec_get_offsets(next_rec, cursor->index, offsets,
+ offsets = rec_get_offsets(next_rec, index, offsets,
n_fields + (n_bytes > 0), &heap);
next_fold = rec_fold(next_rec, offsets, n_fields,
- n_bytes, index_id);
+ n_bytes, index->id);
}
if (!page_rec_is_infimum(rec)) {
- offsets = rec_get_offsets(rec, cursor->index, offsets,
+ offsets = rec_get_offsets(rec, index, offsets,
n_fields + (n_bytes > 0), &heap);
- fold = rec_fold(rec, offsets, n_fields, n_bytes, index_id);
+ fold = rec_fold(rec, offsets, n_fields, n_bytes, index->id);
} else {
if (left_side) {
@@ -1676,6 +1689,10 @@ btr_search_update_hash_on_insert(
locked = TRUE;
+ if (!btr_search_enabled) {
+ goto function_exit;
+ }
+
ha_insert_for_fold(table, ins_fold, block, ins_rec);
}
@@ -1689,6 +1706,10 @@ btr_search_update_hash_on_insert(
rw_lock_x_lock(&btr_search_latch);
locked = TRUE;
+
+ if (!btr_search_enabled) {
+ goto function_exit;
+ }
}
if (!left_side) {
@@ -1707,6 +1728,10 @@ check_next_rec:
rw_lock_x_lock(&btr_search_latch);
locked = TRUE;
+
+ if (!btr_search_enabled) {
+ goto function_exit;
+ }
}
ha_insert_for_fold(table, ins_fold, block, ins_rec);
@@ -1722,6 +1747,10 @@ check_next_rec:
rw_lock_x_lock(&btr_search_latch);
locked = TRUE;
+
+ if (!btr_search_enabled) {
+ goto function_exit;
+ }
}
if (!left_side) {
@@ -1729,7 +1758,7 @@ check_next_rec:
ha_insert_for_fold(table, ins_fold, block, ins_rec);
/*
fputs("Hash insert for ", stderr);
- dict_index_name_print(stderr, cursor->index);
+ dict_index_name_print(stderr, index);
fprintf(stderr, " fold %lu\n", ins_fold);
*/
} else {
@@ -1832,21 +1861,20 @@ btr_search_validate(void)
ut_a(!dict_index_is_ibuf(block->index));
- offsets = rec_get_offsets((const rec_t*) node->data,
+ page_index_id = btr_page_get_index_id(block->frame);
+
+ offsets = rec_get_offsets(node->data,
block->index, offsets,
block->curr_n_fields
+ (block->curr_n_bytes > 0),
&heap);
- page_index_id = btr_page_get_index_id(block->frame);
-
- if (UNIV_UNLIKELY
- (!block->is_hashed || node->fold
- != rec_fold((rec_t*)(node->data),
- offsets,
- block->curr_n_fields,
- block->curr_n_bytes,
- page_index_id))) {
+ if (!block->index || node->fold
+ != rec_fold(node->data,
+ offsets,
+ block->curr_n_fields,
+ block->curr_n_bytes,
+ page_index_id)) {
const page_t* page = block->frame;
ok = FALSE;
@@ -1862,20 +1890,19 @@ btr_search_validate(void)
node->data,
(ullint) page_index_id,
(ulong) node->fold,
- (ulong) rec_fold((rec_t*)(node->data),
+ (ulong) rec_fold(node->data,
offsets,
block->curr_n_fields,
block->curr_n_bytes,
page_index_id));
fputs("InnoDB: Record ", stderr);
- rec_print_new(stderr, (rec_t*)node->data,
- offsets);
+ rec_print_new(stderr, node->data, offsets);
fprintf(stderr, "\nInnoDB: on that page."
- " Page mem address %p, is hashed %lu,"
+ " Page mem address %p, is hashed %p,"
" n fields %lu, n bytes %lu\n"
"InnoDB: side %lu\n",
- (void*) page, (ulong) block->is_hashed,
+ (void*) page, (void*) block->index,
(ulong) block->curr_n_fields,
(ulong) block->curr_n_bytes,
(ulong) block->curr_left_side);
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index 33b4cd40215..b5004a0834c 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -839,6 +839,16 @@ pfs_register_buffer_block(
rwlock->pfs_psi = (PSI_server)
? PSI_server->init_rwlock(buf_block_lock_key, rwlock)
: NULL;
+
+# ifdef UNIV_SYNC_DEBUG
+ rwlock = &block->debug_latch;
+ ut_a(!rwlock->pfs_psi);
+ rwlock->pfs_psi = (PSI_server)
+ ? PSI_server->init_rwlock(buf_block_debug_latch_key,
+ rwlock)
+ : NULL;
+# endif /* UNIV_SYNC_DEBUG */
+
# endif /* UNIV_PFS_RWLOCK */
block++;
}
@@ -873,8 +883,6 @@ buf_block_init(
block->check_index_page_at_flush = FALSE;
block->index = NULL;
- block->is_hashed = FALSE;
-
#ifdef UNIV_DEBUG
block->page.in_page_hash = FALSE;
block->page.in_zip_hash = FALSE;
@@ -897,17 +905,24 @@ buf_block_init(
mutex_create(PFS_NOT_INSTRUMENTED, &block->mutex, SYNC_BUF_BLOCK);
rw_lock_create(PFS_NOT_INSTRUMENTED, &block->lock, SYNC_LEVEL_VARYING);
+
+# ifdef UNIV_SYNC_DEBUG
+ rw_lock_create(PFS_NOT_INSTRUMENTED,
+ &block->debug_latch, SYNC_NO_ORDER_CHECK);
+# endif /* UNIV_SYNC_DEBUG */
+
#else /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */
mutex_create(buffer_block_mutex_key, &block->mutex, SYNC_BUF_BLOCK);
rw_lock_create(buf_block_lock_key, &block->lock, SYNC_LEVEL_VARYING);
+
+# ifdef UNIV_SYNC_DEBUG
+ rw_lock_create(buf_block_debug_latch_key,
+ &block->debug_latch, SYNC_NO_ORDER_CHECK);
+# endif /* UNIV_SYNC_DEBUG */
#endif /* PFS_SKIP_BUFFER_MUTEX_RWLOCK || PFS_GROUP_BUFFER_SYNC */
ut_ad(rw_lock_validate(&(block->lock)));
-#ifdef UNIV_SYNC_DEBUG
- rw_lock_create(buf_block_debug_latch_key,
- &block->debug_latch, SYNC_NO_ORDER_CHECK);
-#endif /* UNIV_SYNC_DEBUG */
}
/********************************************************************//**
@@ -974,11 +989,8 @@ buf_chunk_init(
for (i = chunk->size; i--; ) {
buf_block_init(buf_pool, block, frame);
+ UNIV_MEM_INVALID(block->frame, UNIV_PAGE_SIZE);
-#ifdef HAVE_purify
- /* Wipe contents of frame to eliminate a Purify warning */
- memset(block->frame, '\0', UNIV_PAGE_SIZE);
-#endif
/* Add the block to the free list */
UT_LIST_ADD_LAST(list, buf_pool->free, (&block->page));
@@ -1204,6 +1216,26 @@ buf_pool_free_instance(
{
buf_chunk_t* chunk;
buf_chunk_t* chunks;
+ buf_page_t* bpage;
+
+ bpage = UT_LIST_GET_LAST(buf_pool->LRU);
+ while (bpage != NULL) {
+ buf_page_t* prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
+ enum buf_page_state state = buf_page_get_state(bpage);
+
+ ut_ad(buf_page_in_file(bpage));
+ ut_ad(bpage->in_LRU_list);
+
+ if (state != BUF_BLOCK_FILE_PAGE) {
+ /* We must not have any dirty block except
+ when doing a fast shutdown. */
+ ut_ad(state == BUF_BLOCK_ZIP_PAGE
+ || srv_fast_shutdown == 2);
+ buf_page_free_descriptor(bpage);
+ }
+
+ bpage = prev_bpage;
+ }
chunks = buf_pool->chunks;
chunk = chunks + buf_pool->n_chunks;
@@ -1279,108 +1311,47 @@ buf_pool_free(
}
/********************************************************************//**
-Drops adaptive hash index for a buffer pool instance. */
-static
-void
-buf_pool_drop_hash_index_instance(
-/*==============================*/
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
- ibool* released_search_latch) /*!< out: flag for signalling
- whether the search latch was
- released */
-{
- buf_chunk_t* chunks = buf_pool->chunks;
- buf_chunk_t* chunk = chunks + buf_pool->n_chunks;
-
- while (--chunk >= chunks) {
- ulint i;
- buf_block_t* block = chunk->blocks;
-
- for (i = chunk->size; i--; block++) {
- /* block->is_hashed cannot be modified
- when we have an x-latch on btr_search_latch;
- see the comment in buf0buf.h */
-
- if (!block->is_hashed) {
- continue;
- }
-
- /* To follow the latching order, we
- have to release btr_search_latch
- before acquiring block->latch. */
- rw_lock_x_unlock(&btr_search_latch);
- /* When we release the search latch,
- we must rescan all blocks, because
- some may become hashed again. */
- *released_search_latch = TRUE;
-
- rw_lock_x_lock(&block->lock);
-
- /* This should be guaranteed by the
- callers, which will be holding
- btr_search_enabled_mutex. */
- ut_ad(!btr_search_enabled);
-
- /* Because we did not buffer-fix the
- block by calling buf_block_get_gen(),
- it is possible that the block has been
- allocated for some other use after
- btr_search_latch was released above.
- We do not care which file page the
- block is mapped to. All we want to do
- is to drop any hash entries referring
- to the page. */
-
- /* It is possible that
- block->page.state != BUF_FILE_PAGE.
- Even that does not matter, because
- btr_search_drop_page_hash_index() will
- check block->is_hashed before doing
- anything. block->is_hashed can only
- be set on uncompressed file pages. */
-
- btr_search_drop_page_hash_index(block);
-
- rw_lock_x_unlock(&block->lock);
-
- rw_lock_x_lock(&btr_search_latch);
-
- ut_ad(!btr_search_enabled);
- }
- }
-}
-
-/********************************************************************//**
-Drops the adaptive hash index. To prevent a livelock, this function
-is only to be called while holding btr_search_latch and while
-btr_search_enabled == FALSE. */
+Clears the adaptive hash index on all pages in the buffer pool. */
UNIV_INTERN
void
-buf_pool_drop_hash_index(void)
-/*==========================*/
+buf_pool_clear_hash_index(void)
+/*===========================*/
{
- ibool released_search_latch;
+ ulint p;
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
#endif /* UNIV_SYNC_DEBUG */
ut_ad(!btr_search_enabled);
- do {
- ulint i;
+ for (p = 0; p < srv_buf_pool_instances; p++) {
+ buf_pool_t* buf_pool = buf_pool_from_array(p);
+ buf_chunk_t* chunks = buf_pool->chunks;
+ buf_chunk_t* chunk = chunks + buf_pool->n_chunks;
- released_search_latch = FALSE;
+ while (--chunk >= chunks) {
+ buf_block_t* block = chunk->blocks;
+ ulint i = chunk->size;
- for (i = 0; i < srv_buf_pool_instances; i++) {
- buf_pool_t* buf_pool;
+ for (; i--; block++) {
+ dict_index_t* index = block->index;
- buf_pool = buf_pool_from_array(i);
+ /* We can set block->index = NULL
+ when we have an x-latch on btr_search_latch;
+ see the comment in buf0buf.h */
- buf_pool_drop_hash_index_instance(
- buf_pool, &released_search_latch);
- }
+ if (!index) {
+ /* Not hashed */
+ continue;
+ }
- } while (released_search_latch);
+ block->index = NULL;
+# if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
+ block->n_pointers = 0;
+# endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+ }
+ }
+ }
}
/********************************************************************//**
@@ -1740,38 +1711,6 @@ buf_reset_check_index_page_at_flush(
buf_pool_mutex_exit(buf_pool);
}
-/********************************************************************//**
-Returns the current state of is_hashed of a page. FALSE if the page is
-not in the pool. NOTE that this operation does not fix the page in the
-pool if it is found there.
-@return TRUE if page hash index is built in search system */
-UNIV_INTERN
-ibool
-buf_page_peek_if_search_hashed(
-/*===========================*/
- ulint space, /*!< in: space id */
- ulint offset) /*!< in: page number */
-{
- buf_block_t* block;
- ibool is_hashed;
- buf_pool_t* buf_pool = buf_pool_get(space, offset);
-
- buf_pool_mutex_enter(buf_pool);
-
- block = (buf_block_t*) buf_page_hash_get(buf_pool, space, offset);
-
- if (!block || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
- is_hashed = FALSE;
- } else {
- ut_ad(!buf_pool_watch_is_sentinel(buf_pool, &block->page));
- is_hashed = block->is_hashed;
- }
-
- buf_pool_mutex_exit(buf_pool);
-
- return(is_hashed);
-}
-
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
/********************************************************************//**
Sets file_page_was_freed TRUE if the page is found in the buffer pool.
@@ -1981,7 +1920,6 @@ buf_block_init_low(
block->index = NULL;
block->n_hash_helps = 0;
- block->is_hashed = FALSE;
block->n_fields = 1;
block->n_bytes = 0;
block->left_side = TRUE;
diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
index b5ca21e14a6..510f6eefba5 100644
--- a/storage/innobase/buf/buf0lru.c
+++ b/storage/innobase/buf/buf0lru.c
@@ -273,7 +273,7 @@ next_page:
mutex_enter(&((buf_block_t*) bpage)->mutex);
is_fixed = bpage->buf_fix_count > 0
- || !((buf_block_t*) bpage)->is_hashed;
+ || !((buf_block_t*) bpage)->index;
mutex_exit(&((buf_block_t*) bpage)->mutex);
if (is_fixed) {
@@ -405,7 +405,7 @@ scan_again:
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
/* This is a compressed-only block
descriptor. Do nothing. */
- } else if (((buf_block_t*) bpage)->is_hashed) {
+ } else if (((buf_block_t*) bpage)->index) {
ulint page_no;
ulint zip_size;
@@ -417,7 +417,7 @@ scan_again:
mutex_exit(block_mutex);
/* Note that the following call will acquire
- an S-latch on the page */
+ and release an X-latch on the page. */
btr_search_drop_page_hash_when_freed(
id, zip_size, page_no);
diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
index 3f09732a676..f31e6c03ba1 100644
--- a/storage/innobase/fsp/fsp0fsp.c
+++ b/storage/innobase/fsp/fsp0fsp.c
@@ -332,7 +332,7 @@ fseg_alloc_free_page_low(
inserted there in order, into which
direction they go alphabetically: FSP_DOWN,
FSP_UP, FSP_NO_DIR */
- mtr_t* mtr); /*!< in: mtr handle */
+ mtr_t* mtr); /*!< in/out: mini-transaction */
#endif /* !UNIV_HOTBACKUP */
/**********************************************************************//**
@@ -1547,7 +1547,7 @@ fsp_alloc_free_page(
ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
ulint hint, /*!< in: hint of which page would be desirable */
- mtr_t* mtr) /*!< in: mtr handle */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
fsp_header_t* header;
fil_addr_t first;
@@ -2576,7 +2576,7 @@ fseg_alloc_free_page_low(
inserted there in order, into which
direction they go alphabetically: FSP_DOWN,
FSP_UP, FSP_NO_DIR */
- mtr_t* mtr) /*!< in: mtr handle */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
fsp_header_t* space_header;
ulint space_size;
@@ -2824,7 +2824,7 @@ fseg_alloc_free_page_general(
with fsp_reserve_free_extents, then there
is no need to do the check for this individual
page */
- mtr_t* mtr) /*!< in: mtr handle */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
fseg_inode_t* inode;
ulint space;
diff --git a/storage/innobase/ha/ha0ha.c b/storage/innobase/ha/ha0ha.c
index 7f11917de0a..65046138275 100644
--- a/storage/innobase/ha/ha0ha.c
+++ b/storage/innobase/ha/ha0ha.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2011, 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
@@ -89,40 +89,6 @@ ha_create_func(
}
/*************************************************************//**
-Empties a hash table and frees the memory heaps. */
-UNIV_INTERN
-void
-ha_clear(
-/*=====*/
- hash_table_t* table) /*!< in, own: hash table */
-{
- ulint i;
- ulint n;
-
- ut_ad(table);
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
-#ifdef UNIV_SYNC_DEBUG
- ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EXCLUSIVE));
-#endif /* UNIV_SYNC_DEBUG */
-
-#ifndef UNIV_HOTBACKUP
- /* Free the memory heaps. */
- n = table->n_mutexes;
-
- for (i = 0; i < n; i++) {
- mem_heap_free(table->heaps[i]);
- }
-#endif /* !UNIV_HOTBACKUP */
-
- /* Clear the hash table. */
- n = hash_get_n_cells(table);
-
- for (i = 0; i < n; i++) {
- hash_get_nth_cell(table, i)->node = NULL;
- }
-}
-
-/*************************************************************//**
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
is inserted. If btr_search_enabled is set to FALSE, we will only allow
@@ -140,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 */
- void* data) /*!< in: data, must not be NULL */
+ const rec_t* data) /*!< in: data, must not be NULL */
{
hash_cell_t* cell;
ha_node_t* node;
@@ -153,7 +119,11 @@ ha_insert_for_fold_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(block->frame == page_align(data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
+#endif /* UNIV_SYNC_DEBUG */
ASSERT_HASH_MUTEX_OWN(table, fold);
+ ut_ad(btr_search_enabled);
hash = hash_calc_hash(fold, table);
@@ -173,7 +143,6 @@ ha_insert_for_fold_func(
prev_block->n_pointers--;
block->n_pointers++;
}
- ut_ad(!btr_search_fully_disabled);
# endif /* !UNIV_HOTBACKUP */
prev_node->block = block;
@@ -186,13 +155,6 @@ ha_insert_for_fold_func(
prev_node = prev_node->next;
}
- /* We are in the process of disabling hash index, do not add
- new chain node */
- if (!btr_search_enabled) {
- ut_ad(!btr_search_fully_disabled);
- return(TRUE);
- }
-
/* We have to allocate a new chain node */
node = mem_heap_alloc(hash_get_heap(table, fold), sizeof(ha_node_t));
@@ -250,6 +212,10 @@ ha_delete_hash_node(
{
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
+#endif /* UNIV_SYNC_DEBUG */
+ ut_ad(btr_search_enabled);
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
# ifndef UNIV_HOTBACKUP
if (table->adaptive) {
@@ -272,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 */
- void* data, /*!< in: pointer to the data */
+ const 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 */
- void* new_data)/*!< in: new pointer to the data */
+ const rec_t* new_data)/*!< in: new pointer to the data */
{
ha_node_t* node;
@@ -286,6 +252,13 @@ ha_search_and_update_if_found_func(
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
ut_a(new_block->frame == page_align(new_data));
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
+#endif /* UNIV_SYNC_DEBUG */
+
+ if (!btr_search_enabled) {
+ return;
+ }
node = ha_search_with_data(table, fold, data);
@@ -322,6 +295,10 @@ ha_remove_all_nodes_to_page(
ut_ad(table);
ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
ASSERT_HASH_MUTEX_OWN(table, fold);
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
+#endif /* UNIV_SYNC_DEBUG */
+ ut_ad(btr_search_enabled);
node = ha_chain_get_first(table, fold);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index af730f57cb5..9a8bd67e8a4 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -2580,7 +2580,6 @@ innobase_change_buffering_inited_ok:
/* Get the current high water mark format. */
innobase_file_format_max = (char*) trx_sys_file_format_max_get();
- btr_search_fully_disabled = (!btr_search_enabled);
DBUG_RETURN(FALSE);
error:
DBUG_RETURN(TRUE);
@@ -5091,8 +5090,7 @@ no_commit:
switch (sql_command) {
case SQLCOM_LOAD:
- if ((trx->duplicates
- & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))) {
+ if (trx->duplicates) {
goto set_max_autoinc;
}
@@ -5269,14 +5267,15 @@ calc_row_difference(
/* The field has changed */
ufield = uvect->fields + n_changed;
+ UNIV_MEM_INVALID(ufield, sizeof *ufield);
/* Let us use a dummy dfield to make the conversion
from the MySQL column format to the InnoDB format */
- dict_col_copy_type(prebuilt->table->cols + i,
- dfield_get_type(&dfield));
-
if (n_len != UNIV_SQL_NULL) {
+ dict_col_copy_type(prebuilt->table->cols + i,
+ dfield_get_type(&dfield));
+
buf = row_mysql_store_col_in_innobase_format(
&dfield,
(byte*)buf,
@@ -5284,7 +5283,7 @@ calc_row_difference(
new_mysql_row_col,
col_pack_len,
dict_table_is_comp(prebuilt->table));
- dfield_copy_data(&ufield->new_val, &dfield);
+ dfield_copy(&ufield->new_val, &dfield);
} else {
dfield_set_null(&ufield->new_val);
}
@@ -5367,8 +5366,7 @@ ha_innobase::update_row(
&& table->next_number_field
&& new_row == table->record[0]
&& thd_sql_command(user_thd) == SQLCOM_INSERT
- && (trx->duplicates & (TRX_DUP_IGNORE | TRX_DUP_REPLACE))
- == TRX_DUP_IGNORE) {
+ && trx->duplicates) {
ulonglong auto_inc;
ulonglong col_max_value;
@@ -5728,6 +5726,7 @@ ha_innobase::index_read(
(byte*) key_ptr,
(ulint) key_len,
prebuilt->trx);
+ DBUG_ASSERT(prebuilt->search_tuple->n_fields > 0);
} else {
/* We position the cursor to the last or the first entry
in the index */
@@ -7556,6 +7555,7 @@ 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()));
@@ -7605,6 +7605,9 @@ ha_innobase::records_in_range(
(const uchar*) 0),
(ulint) (min_key ? min_key->length : 0),
prebuilt->trx);
+ DBUG_ASSERT(min_key
+ ? range_start->n_fields > 0
+ : range_start->n_fields == 0);
row_sel_convert_mysql_key_to_innobase(
range_end, (byte*) key_val_buff2,
@@ -7613,6 +7616,9 @@ ha_innobase::records_in_range(
(const uchar*) 0),
(ulint) (max_key ? max_key->length : 0),
prebuilt->trx);
+ DBUG_ASSERT(max_key
+ ? range_end->n_fields > 0
+ : range_end->n_fields == 0);
mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag :
HA_READ_KEY_EXACT);
@@ -8865,6 +8871,7 @@ ha_innobase::extra(
break;
case HA_EXTRA_RESET_STATE:
reset_template(prebuilt);
+ thd_to_trx(ha_thd())->duplicates = 0;
break;
case HA_EXTRA_NO_KEYREAD:
prebuilt->read_just_key = 0;
@@ -8882,19 +8889,18 @@ ha_innobase::extra(
parameters below. We must not invoke update_thd()
either, because the calling threads may change.
CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
- case HA_EXTRA_IGNORE_DUP_KEY:
+ case HA_EXTRA_INSERT_WITH_UPDATE:
thd_to_trx(ha_thd())->duplicates |= TRX_DUP_IGNORE;
break;
+ case HA_EXTRA_NO_IGNORE_DUP_KEY:
+ thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_IGNORE;
+ break;
case HA_EXTRA_WRITE_CAN_REPLACE:
thd_to_trx(ha_thd())->duplicates |= TRX_DUP_REPLACE;
break;
case HA_EXTRA_WRITE_CANNOT_REPLACE:
thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE;
break;
- case HA_EXTRA_NO_IGNORE_DUP_KEY:
- thd_to_trx(ha_thd())->duplicates &=
- ~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
- break;
default:/* Do nothing */
;
}
diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
index 7f6acb2b042..0676a7be0f7 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -3955,7 +3955,7 @@ ibuf_insert_to_index_page(
ut_ad(ibuf_inside(mtr));
ut_ad(dtuple_check_typed(entry));
- ut_ad(!buf_block_align(page)->is_hashed);
+ ut_ad(!buf_block_align(page)->index);
if (UNIV_UNLIKELY(dict_table_is_comp(index->table)
!= (ibool)!!page_is_comp(page))) {
diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h
index f605c476844..140f94466db 100644
--- a/storage/innobase/include/btr0pcur.h
+++ b/storage/innobase/include/btr0pcur.h
@@ -263,14 +263,6 @@ btr_pcur_commit_specify_mtr(
/*========================*/
btr_pcur_t* pcur, /*!< in: persistent cursor */
mtr_t* mtr); /*!< in: mtr to commit */
-/**************************************************************//**
-Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
-@return TRUE if detached */
-UNIV_INLINE
-ibool
-btr_pcur_is_detached(
-/*=================*/
- btr_pcur_t* pcur); /*!< in: persistent cursor */
/*********************************************************//**
Moves the persistent cursor to the next record in the tree. If no records are
left, the cursor stays 'after last in tree'.
diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic
index d86601e5a32..054ce753c7d 100644
--- a/storage/innobase/include/btr0pcur.ic
+++ b/storage/innobase/include/btr0pcur.ic
@@ -389,38 +389,6 @@ btr_pcur_commit_specify_mtr(
}
/**************************************************************//**
-Sets the pcur latch mode to BTR_NO_LATCHES. */
-UNIV_INLINE
-void
-btr_pcur_detach(
-/*============*/
- btr_pcur_t* pcur) /*!< in: persistent cursor */
-{
- ut_a(pcur->pos_state == BTR_PCUR_IS_POSITIONED);
-
- pcur->latch_mode = BTR_NO_LATCHES;
-
- pcur->pos_state = BTR_PCUR_WAS_POSITIONED;
-}
-
-/**************************************************************//**
-Tests if a cursor is detached: that is the latch mode is BTR_NO_LATCHES.
-@return TRUE if detached */
-UNIV_INLINE
-ibool
-btr_pcur_is_detached(
-/*=================*/
- btr_pcur_t* pcur) /*!< in: persistent cursor */
-{
- if (pcur->latch_mode == BTR_NO_LATCHES) {
-
- return(TRUE);
- }
-
- return(FALSE);
-}
-
-/**************************************************************//**
Sets the old_rec_buf field to NULL. */
UNIV_INLINE
void
diff --git a/storage/innobase/include/btr0sea.h b/storage/innobase/include/btr0sea.h
index 6493689a969..1f920471f7d 100644
--- a/storage/innobase/include/btr0sea.h
+++ b/storage/innobase/include/btr0sea.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2011, 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
@@ -141,8 +141,8 @@ btr_search_drop_page_hash_index(
for which we know that
block->buf_fix_count == 0 */
/********************************************************************//**
-Drops a page hash index when a page is freed from a fseg to the file system.
-Drops possible hash index if the page happens to be in the buffer pool. */
+Drops a possible page hash index when a page is evicted from the buffer pool
+or freed in a file segment. */
UNIV_INTERN
void
btr_search_drop_page_hash_when_freed(
@@ -192,16 +192,6 @@ btr_search_validate(void);
# define btr_search_validate() TRUE
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
-/** Flag: has the search system been enabled?
-Protected by btr_search_latch and btr_search_enabled_mutex. */
-extern char btr_search_enabled;
-
-/** Flag: whether the search system has completed its disabling process,
-It is set to TRUE right after buf_pool_drop_hash_index() in
-btr_search_disable(), indicating hash index entries are cleaned up.
-Protected by btr_search_latch and btr_search_enabled_mutex. */
-extern ibool btr_search_fully_disabled;
-
/** The search info struct in an index */
struct btr_search_struct{
ulint ref_count; /*!< Number of blocks in this index tree
@@ -270,24 +260,6 @@ struct btr_search_sys_struct{
/** The adaptive hash index */
extern btr_search_sys_t* btr_search_sys;
-/** @brief The latch protecting the adaptive search system
-
-This latch protects the
-(1) hash index;
-(2) columns of a record to which we have a pointer in the hash index;
-
-but does NOT protect:
-
-(3) next record offset field in a record;
-(4) next or previous records on the same page.
-
-Bear in mind (3) and (4) when using the hash index.
-*/
-extern rw_lock_t* btr_search_latch_temp;
-
-/** The latch protecting the adaptive search system */
-#define btr_search_latch (*btr_search_latch_temp)
-
#ifdef UNIV_SEARCH_PERF_STAT
/** Number of successful adaptive hash index lookups */
extern ulint btr_search_n_succ;
diff --git a/storage/innobase/include/btr0types.h b/storage/innobase/include/btr0types.h
index 07c06fb18d7..5adc858b931 100644
--- a/storage/innobase/include/btr0types.h
+++ b/storage/innobase/include/btr0types.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2011, 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
@@ -30,6 +30,7 @@ Created 2/17/1996 Heikki Tuuri
#include "rem0types.h"
#include "page0types.h"
+#include "sync0rw.h"
/** Persistent cursor */
typedef struct btr_pcur_struct btr_pcur_t;
@@ -38,6 +39,28 @@ typedef struct btr_cur_struct btr_cur_t;
/** B-tree search information for the adaptive hash index */
typedef struct btr_search_struct btr_search_t;
+/** @brief The latch protecting the adaptive search system
+
+This latch protects the
+(1) hash index;
+(2) columns of a record to which we have a pointer in the hash index;
+
+but does NOT protect:
+
+(3) next record offset field in a record;
+(4) next or previous records on the same page.
+
+Bear in mind (3) and (4) when using the hash index.
+*/
+extern rw_lock_t* btr_search_latch_temp;
+
+/** The latch protecting the adaptive search system */
+#define btr_search_latch (*btr_search_latch_temp)
+
+/** Flag: has the search system been enabled?
+Protected by btr_search_latch. */
+extern char btr_search_enabled;
+
#ifdef UNIV_BLOB_DEBUG
# include "buf0types.h"
/** An index->blobs entry for keeping track of off-page column references */
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index ccebb69a4fe..c0ff7b1766b 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -229,13 +229,11 @@ buf_pool_free(
ulint n_instances); /*!< in: numbere of instances to free */
/********************************************************************//**
-Drops the adaptive hash index. To prevent a livelock, this function
-is only to be called while holding btr_search_latch and while
-btr_search_enabled == FALSE. */
+Clears the adaptive hash index on all pages in the buffer pool. */
UNIV_INTERN
void
-buf_pool_drop_hash_index(void);
-/*==========================*/
+buf_pool_clear_hash_index(void);
+/*===========================*/
/********************************************************************//**
Relocate a buffer control block. Relocates the block on the LRU list
@@ -568,17 +566,6 @@ buf_page_peek_if_too_old(
/*=====================*/
const buf_page_t* bpage); /*!< in: block to make younger */
/********************************************************************//**
-Returns the current state of is_hashed of a page. FALSE if the page is
-not in the pool. NOTE that this operation does not fix the page in the
-pool if it is found there.
-@return TRUE if page hash index is built in search system */
-UNIV_INTERN
-ibool
-buf_page_peek_if_search_hashed(
-/*===========================*/
- ulint space, /*!< in: space id */
- ulint offset);/*!< in: page number */
-/********************************************************************//**
Gets the youngest modification log sequence number for a frame.
Returns zero if not file page or no modification occurred yet.
@return newest modification to page */
@@ -1526,13 +1513,16 @@ struct buf_block_struct{
/* @} */
/** @name Hash search fields
- These 6 fields may only be modified when we have
+ These 5 fields may only be modified when we have
an x-latch on btr_search_latch AND
- we are holding an s-latch or x-latch on buf_block_struct::lock or
- we know that buf_block_struct::buf_fix_count == 0.
An exception to this is when we init or create a page
- in the buffer pool in buf0buf.c. */
+ in the buffer pool in buf0buf.c.
+
+ Another exception is that assigning block->index = NULL
+ is allowed whenever holding an x-latch on btr_search_latch. */
/* @{ */
@@ -1541,20 +1531,20 @@ struct buf_block_struct{
pointers in the adaptive hash index
pointing to this frame */
#endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */
- unsigned is_hashed:1; /*!< TRUE if hash index has
- already been built on this
- page; note that it does not
- guarantee that the index is
- complete, though: there may
- have been hash collisions,
- record deletions, etc. */
unsigned curr_n_fields:10;/*!< prefix length for hash indexing:
number of full fields */
unsigned curr_n_bytes:15;/*!< number of bytes in hash
indexing */
unsigned curr_left_side:1;/*!< TRUE or FALSE in hash indexing */
- dict_index_t* index; /*!< Index for which the adaptive
- hash index has been created. */
+ dict_index_t* index; /*!< Index for which the
+ adaptive hash index has been
+ created, or NULL if the page
+ does not exist in the
+ index. Note that it does not
+ guarantee that the index is
+ complete, though: there may
+ have been hash collisions,
+ record deletions, etc. */
/* @} */
# ifdef UNIV_SYNC_DEBUG
/** @name Debug fields */
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 7abd3914eda..6e70fbf6f66 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -210,7 +210,8 @@ fseg_alloc_free_page_general(
with fsp_reserve_free_extents, then there
is no need to do the check for this individual
page */
- mtr_t* mtr); /*!< in: mtr handle */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
+ __attribute__((warn_unused_result, nonnull(1,5)));
/**********************************************************************//**
Reserves free pages from a tablespace. All mini-transactions which may
use several pages from the tablespace should call this function beforehand
diff --git a/storage/innobase/include/ha0ha.h b/storage/innobase/include/ha0ha.h
index 3299000bf3c..8bba564d153 100644
--- a/storage/innobase/include/ha0ha.h
+++ b/storage/innobase/include/ha0ha.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2011, 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
@@ -31,13 +31,14 @@ Created 8/18/1994 Heikki Tuuri
#include "hash0hash.h"
#include "page0types.h"
#include "buf0types.h"
+#include "rem0types.h"
/*************************************************************//**
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
-void*
+const rec_t*
ha_search_and_get_data(
/*===================*/
hash_table_t* table, /*!< in: hash table */
@@ -51,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 */
- void* data, /*!< in: pointer to the data */
+ const 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 */
- void* new_data);/*!< in: new pointer to the data */
+ const 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
@@ -114,14 +115,6 @@ chosen to be a slightly bigger prime number.
#endif /* UNIV_SYNC_DEBUG */
/*************************************************************//**
-Empties a hash table and frees the memory heaps. */
-UNIV_INTERN
-void
-ha_clear(
-/*=====*/
- hash_table_t* table); /*!< in, own: hash table */
-
-/*************************************************************//**
Inserts an entry into a hash table. If an entry with the same fold number
is found, its node is updated to point to the new data, and no new node
is inserted.
@@ -138,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 */
- void* data); /*!< in: data, must not be NULL */
+ const rec_t* data); /*!< in: data, must not be NULL */
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
/**
@@ -174,7 +167,7 @@ ha_search_and_delete_if_found(
/*==========================*/
hash_table_t* table, /*!< in: hash table */
ulint fold, /*!< in: folded value of the searched data */
- void* data); /*!< in: pointer to the data */
+ const rec_t* data); /*!< in: pointer to the data */
#ifndef UNIV_HOTBACKUP
/*****************************************************************//**
Removes from the chain determined by fold all nodes whose data pointer
@@ -217,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 */
- void* data; /*!< pointer to the data */
+ const rec_t* data; /*!< pointer to the data */
ulint fold; /*!< fold value for the data */
};
diff --git a/storage/innobase/include/ha0ha.ic b/storage/innobase/include/ha0ha.ic
index 734403c4cd9..5656e9b7eba 100644
--- a/storage/innobase/include/ha0ha.ic
+++ b/storage/innobase/include/ha0ha.ic
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1994, 2011, 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
@@ -25,6 +25,7 @@ Created 8/18/1994 Heikki Tuuri
#include "ut0rnd.h"
#include "mem0mem.h"
+#include "btr0types.h"
/***********************************************************//**
Deletes a hash node. */
@@ -39,10 +40,10 @@ ha_delete_hash_node(
Gets a hash node data.
@return pointer to the data */
UNIV_INLINE
-void*
+const rec_t*
ha_node_get_data(
/*=============*/
- ha_node_t* node) /*!< in: hash chain node */
+ const ha_node_t* node) /*!< in: hash chain node */
{
return(node->data);
}
@@ -57,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 */
- void* data) /*!< in: pointer to the data */
+ const rec_t* data) /*!< in: pointer to the data */
{
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
node->block = block;
@@ -107,39 +108,10 @@ ha_chain_get_first(
/*************************************************************//**
Looks for an element in a hash table.
-@return pointer to the first hash table node in chain having the fold
-number, NULL if not found */
-UNIV_INLINE
-ha_node_t*
-ha_search(
-/*======*/
- hash_table_t* table, /*!< in: hash table */
- ulint fold) /*!< in: folded value of the searched data */
-{
- ha_node_t* node;
-
- ASSERT_HASH_MUTEX_OWN(table, fold);
-
- node = ha_chain_get_first(table, fold);
-
- while (node) {
- if (node->fold == fold) {
-
- return(node);
- }
-
- node = ha_chain_get_next(node);
- }
-
- return(NULL);
-}
-
-/*************************************************************//**
-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
-void*
+const rec_t*
ha_search_and_get_data(
/*===================*/
hash_table_t* table, /*!< in: hash table */
@@ -148,6 +120,10 @@ ha_search_and_get_data(
ha_node_t* node;
ASSERT_HASH_MUTEX_OWN(table, fold);
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
+#endif /* UNIV_SYNC_DEBUG */
+ ut_ad(btr_search_enabled);
node = ha_chain_get_first(table, fold);
@@ -172,12 +148,14 @@ ha_search_with_data(
/*================*/
hash_table_t* table, /*!< in: hash table */
ulint fold, /*!< in: folded value of the searched data */
- void* data) /*!< in: pointer to the data */
+ const rec_t* data) /*!< in: pointer to the data */
{
ha_node_t* node;
ASSERT_HASH_MUTEX_OWN(table, fold);
+ ut_ad(btr_search_enabled);
+
node = ha_chain_get_first(table, fold);
while (node) {
@@ -202,11 +180,15 @@ ha_search_and_delete_if_found(
/*==========================*/
hash_table_t* table, /*!< in: hash table */
ulint fold, /*!< in: folded value of the searched data */
- void* data) /*!< in: pointer to the data */
+ const rec_t* data) /*!< in: pointer to the data */
{
ha_node_t* node;
ASSERT_HASH_MUTEX_OWN(table, fold);
+#ifdef UNIV_SYNC_DEBUG
+ ut_ad(rw_lock_own(&btr_search_latch, RW_LOCK_EX));
+#endif /* UNIV_SYNC_DEBUG */
+ ut_ad(btr_search_enabled);
node = ha_search_with_data(table, fold, data);
diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic
index 1db4a4bd735..960c25d6051 100644
--- a/storage/innobase/include/mtr0mtr.ic
+++ b/storage/innobase/include/mtr0mtr.ic
@@ -44,7 +44,6 @@ mtr_start(
mtr->log_mode = MTR_LOG_ALL;
mtr->modifications = FALSE;
- mtr->inside_ibuf = FALSE;
mtr->n_log_recs = 0;
ut_d(mtr->state = MTR_ACTIVE);
diff --git a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic
index 11db82f64da..10646241125 100644
--- a/storage/innobase/include/row0upd.ic
+++ b/storage/innobase/include/row0upd.ic
@@ -28,7 +28,6 @@ Created 12/27/1996 Heikki Tuuri
# include "trx0trx.h"
# include "trx0undo.h"
# include "row0row.h"
-# include "btr0sea.h"
#endif /* !UNIV_HOTBACKUP */
#include "page0zip.h"
diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h
index d9dea0aa63d..b5bf30e758c 100644
--- a/storage/innobase/include/sync0sync.h
+++ b/storage/innobase/include/sync0sync.h
@@ -670,7 +670,6 @@ or row lock! */
#define SYNC_LOG_FLUSH_ORDER 147
#define SYNC_RECV 168
#define SYNC_WORK_QUEUE 162
-#define SYNC_SEARCH_SYS_CONF 161 /* for assigning btr_search_enabled */
#define SYNC_SEARCH_SYS 160 /* NOTE that if we have a memory
heap that can be extended to the
buffer pool, its logical level is
diff --git a/storage/innobase/page/page0page.c b/storage/innobase/page/page0page.c
index 6064d028ae1..102274d66f3 100644
--- a/storage/innobase/page/page0page.c
+++ b/storage/innobase/page/page0page.c
@@ -215,12 +215,6 @@ page_set_max_trx_id(
{
page_t* page = buf_block_get_frame(block);
#ifndef UNIV_HOTBACKUP
- const ibool is_hashed = block->is_hashed;
-
- if (is_hashed) {
- rw_lock_x_lock(&btr_search_latch);
- }
-
ut_ad(!mtr || mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
#endif /* !UNIV_HOTBACKUP */
@@ -241,12 +235,6 @@ page_set_max_trx_id(
} else {
mach_write_to_8(page + (PAGE_HEADER + PAGE_MAX_TRX_ID), trx_id);
}
-
-#ifndef UNIV_HOTBACKUP
- if (is_hashed) {
- rw_lock_x_unlock(&btr_search_latch);
- }
-#endif /* !UNIV_HOTBACKUP */
}
/************************************************************//**
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index 2925feb2904..6e311ce2e80 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -437,11 +437,9 @@ row_ins_cascade_calc_update_vec(
dict_table_t* table = foreign->foreign_table;
dict_index_t* index = foreign->foreign_index;
upd_t* update;
- upd_field_t* ufield;
dict_table_t* parent_table;
dict_index_t* parent_index;
upd_t* parent_update;
- upd_field_t* parent_ufield;
ulint n_fields_updated;
ulint parent_field_no;
ulint i;
@@ -477,13 +475,15 @@ row_ins_cascade_calc_update_vec(
dict_index_get_nth_col_no(parent_index, i));
for (j = 0; j < parent_update->n_fields; j++) {
- parent_ufield = parent_update->fields + j;
+ const upd_field_t* parent_ufield
+ = &parent_update->fields[j];
if (parent_ufield->field_no == parent_field_no) {
ulint min_size;
const dict_col_t* col;
ulint ufield_len;
+ upd_field_t* ufield;
col = dict_index_get_nth_col(index, i);
@@ -496,6 +496,8 @@ row_ins_cascade_calc_update_vec(
ufield->field_no
= dict_table_get_nth_col_pos(
table, dict_col_get_no(col));
+
+ ufield->orig_len = 0;
ufield->exp = NULL;
ufield->new_val = parent_ufield->new_val;
@@ -983,10 +985,9 @@ row_ins_foreign_check_on_constraint(
goto nonstandard_exit_func;
}
- if ((node->is_delete
- && (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL))
- || (!node->is_delete
- && (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL))) {
+ if (node->is_delete
+ ? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
+ : (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)) {
/* Build the appropriate update vector which sets
foreign->n_fields first fields in rec to SQL NULL */
@@ -995,6 +996,8 @@ row_ins_foreign_check_on_constraint(
update->info_bits = 0;
update->n_fields = foreign->n_fields;
+ UNIV_MEM_INVALID(update->fields,
+ update->n_fields * sizeof *update->fields);
for (i = 0; i < foreign->n_fields; i++) {
upd_field_t* ufield = &update->fields[i];
@@ -1652,7 +1655,7 @@ row_ins_scan_sec_index_for_duplicate(
ulint n_fields_cmp;
btr_pcur_t pcur;
ulint err = DB_SUCCESS;
- unsigned allow_duplicates;
+ ulint allow_duplicates;
mtr_t mtr;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
@@ -1683,7 +1686,7 @@ row_ins_scan_sec_index_for_duplicate(
btr_pcur_open(index, entry, PAGE_CUR_GE, BTR_SEARCH_LEAF, &pcur, &mtr);
- allow_duplicates = thr_get_trx(thr)->duplicates & TRX_DUP_IGNORE;
+ allow_duplicates = thr_get_trx(thr)->duplicates;
/* Scan index records and check if there is a duplicate */
@@ -1817,7 +1820,7 @@ row_ins_duplicate_error_in_clust(
sure that in roll-forward we get the same duplicate
errors as in original execution */
- if (trx->duplicates & TRX_DUP_IGNORE) {
+ if (trx->duplicates) {
/* If the SQL-query will update or replace
duplicate key we will take X-lock for
@@ -1861,7 +1864,7 @@ row_ins_duplicate_error_in_clust(
offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
- if (trx->duplicates & TRX_DUP_IGNORE) {
+ if (trx->duplicates) {
/* If the SQL-query will update or replace
duplicate key we will take X-lock for
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index d0bedd69842..d06411e09f0 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2000, 2010, Innobase Oy. All Rights Reserved.
+Copyright (c) 2000, 2011, 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
@@ -3995,6 +3995,7 @@ end:
trx->error_state = DB_SUCCESS;
trx_general_rollback_for_mysql(trx, NULL);
trx->error_state = DB_SUCCESS;
+ err = DB_ERROR;
goto funct_exit;
}
diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index 993d44173ee..81efe50d9bd 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/sync/sync0sync.c
@@ -1216,7 +1216,6 @@ sync_thread_add_level(
case SYNC_FILE_FORMAT_TAG:
case SYNC_DOUBLEWRITE:
case SYNC_SEARCH_SYS:
- case SYNC_SEARCH_SYS_CONF:
case SYNC_TRX_LOCK_HEAP:
case SYNC_KERNEL:
case SYNC_IBUF_BITMAP_MUTEX:
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 0b58afc23c9..0e319874837 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -66,7 +66,7 @@ ulonglong pagecache_buffer_size;
good. It would happen only after Recovery, if the table is still
corrupted.
*/
-ulong maria_recover_options= HA_RECOVER_NONE;
+ulonglong maria_recover_options= HA_RECOVER_NONE;
handlerton *maria_hton;
/* bits in maria_recover_options */
@@ -76,10 +76,9 @@ const char *maria_recover_names[]=
Compared to MyISAM, "default" was renamed to "normal" as it collided with
SET var=default which sets to the var's default i.e. what happens when the
var is not set i.e. HA_RECOVER_NONE.
- Another change is that OFF is used to disable, not ""; this is to have OFF
- display in SHOW VARIABLES which is better than "".
+ OFF flag is ignored.
*/
- "OFF", "NORMAL", "BACKUP", "FORCE", "QUICK", NullS
+ "NORMAL", "BACKUP", "FORCE", "QUICK", "OFF", NullS
};
TYPELIB maria_recover_typelib=
{
@@ -240,28 +239,28 @@ static MYSQL_SYSVAR_ULONGLONG(pagecache_buffer_size, pagecache_buffer_size,
"The size of the buffer used for index blocks for Aria tables. "
"Increase this to get better index handling (for all reads and "
"multiple writes) to as much as you can afford.", 0, 0,
- KEY_CACHE_SIZE, 8192*16L, ~(ulong) 0, 1);
+ KEY_CACHE_SIZE, 8192*16L, ~(ulonglong) 0, 1);
static MYSQL_SYSVAR_ULONG(pagecache_division_limit, pagecache_division_limit,
PLUGIN_VAR_RQCMDARG,
"The minimum percentage of warm blocks in key cache", 0, 0,
100, 1, 100, 1);
-static MYSQL_SYSVAR_ENUM(recover, maria_recover_options, PLUGIN_VAR_OPCMDARG,
+static MYSQL_SYSVAR_SET(recover, maria_recover_options, PLUGIN_VAR_OPCMDARG,
"Specifies how corrupted tables should be automatically repaired."
- " Possible values are \"NORMAL\" (the default), \"BACKUP\", \"FORCE\","
- " \"QUICK\", or \"OFF\" which is like not using the option.",
+ " Possible values are one or more of \"NORMAL\" (the default), "
+ "\"BACKUP\", \"FORCE\", or \"QUICK\".",
NULL, NULL, HA_RECOVER_DEFAULT, &maria_recover_typelib);
static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG,
"Number of threads to use when repairing Aria tables. The value of 1 "
"disables parallel repair.",
- 0, 0, 1, 1, ~0L, 1);
+ 0, 0, 1, 1, 128, 1);
static MYSQL_THDVAR_ULONG(sort_buffer_size, PLUGIN_VAR_RQCMDARG,
"The buffer that is allocated when sorting the index when doing a "
"REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE.",
- 0, 0, 128L*1024L*1024L, 4, ~0L, 1);
+ 0, 0, 128L*1024L*1024L, 4, UINT_MAX32, 1);
static MYSQL_THDVAR_ENUM(stats_method, PLUGIN_VAR_RQCMDARG,
"Specifies how Aria index statistics collection code should treat "
@@ -1143,7 +1142,7 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
test_if_locked|= HA_OPEN_MMAP;
#endif
- if (unlikely(maria_recover_options != HA_RECOVER_NONE))
+ if (maria_recover_options & HA_RECOVER_ANY)
{
/* user asked to trigger a repair if table was not properly closed */
test_if_locked|= HA_OPEN_ABORT_IF_CRASHED;
@@ -1460,8 +1459,12 @@ int ha_maria::zerofill(THD * thd, HA_CHECK_OPT *check_opt)
if (!error)
{
+ TrID create_trid= trnman_get_min_safe_trid();
mysql_mutex_lock(&share->intern_lock);
+ share->state.changed|= STATE_NOT_MOVABLE;
maria_update_state_info(&param, file, UPDATE_TIME | UPDATE_OPEN_COUNT);
+ _ma_update_state_lsns_sub(share, LSN_IMPOSSIBLE, create_trid,
+ TRUE, TRUE);
mysql_mutex_unlock(&share->intern_lock);
}
return error;
@@ -1650,9 +1653,6 @@ int ha_maria::repair(THD *thd, HA_CHECK *param, bool do_optimize)
_ma_check_print_warning(param, "Number of rows changed from %s to %s",
llstr(rows, llbuff),
llstr(file->state->records, llbuff2));
- /* Abort if warning was converted to error */
- if (table->in_use->is_error())
- error= 1;
}
}
else
@@ -2517,9 +2517,17 @@ int ha_maria::extra_opt(enum ha_extra_function operation, ulong cache_size)
int ha_maria::delete_all_rows()
{
+#ifdef EXTRA_DEBUG
THD *thd= table->in_use;
- (void) translog_log_debug_info(file->trn, LOGREC_DEBUG_INFO_QUERY,
- (uchar*) thd->query(), thd->query_length());
+ TRN *trn= file->trn;
+ if (trn && ! (trnman_get_flags(trn) & TRN_STATE_INFO_LOGGED))
+ {
+ trnman_set_flags(trn, trnman_get_flags(trn) | TRN_STATE_INFO_LOGGED |
+ TRN_STATE_TABLES_CAN_CHANGE);
+ (void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY,
+ (uchar*) thd->query(), thd->query_length());
+ }
+#endif
if (file->s->now_transactional &&
((table->in_use->variables.option_bits & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
table->in_use->locked_tables_mode))
@@ -3344,7 +3352,7 @@ static int mark_recovery_start(const char* log_dir)
{
int res;
DBUG_ENTER("mark_recovery_start");
- if (unlikely(maria_recover_options == HA_RECOVER_NONE))
+ if (!(maria_recover_options & HA_RECOVER_ANY))
ma_message_no_user(ME_JUST_WARNING, "Please consider using option"
" --aria-recover[=...] to automatically check and"
" repair tables when logs are removed by option"
diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h
index dba0aeaa20e..6232333a160 100644
--- a/storage/maria/ha_maria.h
+++ b/storage/maria/ha_maria.h
@@ -37,7 +37,7 @@ C_MODE_END
extern ulong maria_sort_buffer_size;
extern TYPELIB maria_recover_typelib;
-extern ulong maria_recover_options;
+extern ulonglong maria_recover_options;
class ha_maria :public handler
{
@@ -152,7 +152,8 @@ public:
bool check_and_repair(THD * thd);
bool is_crashed() const;
bool is_changed() const;
- bool auto_repair() const { return maria_recover_options != HA_RECOVER_NONE; }
+ bool auto_repair() const
+ { return test(maria_recover_options & HA_RECOVER_ANY); }
int optimize(THD * thd, HA_CHECK_OPT * check_opt);
int restore(THD * thd, HA_CHECK_OPT * check_opt);
int backup(THD * thd, HA_CHECK_OPT * check_opt);
diff --git a/storage/maria/ma_bitmap.c b/storage/maria/ma_bitmap.c
index ab9b49b6219..b55b633e398 100644
--- a/storage/maria/ma_bitmap.c
+++ b/storage/maria/ma_bitmap.c
@@ -286,16 +286,16 @@ my_bool _ma_bitmap_init(MARIA_SHARE *share, File file,
*/
{
pgcache_page_no_t last_bitmap_page;
- pgcache_page_no_t blocks, bytes;
+ ulong blocks, bytes;
last_bitmap_page= *last_page - *last_page % bitmap->pages_covered;
- blocks= *last_page - last_bitmap_page;
+ blocks= (ulong) (*last_page - last_bitmap_page);
bytes= (blocks * 3) / 8; /* 3 bit per page / 8 bits per byte */
/* Size needs to be aligned on 6 */
bytes/= 6;
bytes*= 6;
bitmap->last_bitmap_page= last_bitmap_page;
- bitmap->last_total_size= bytes;
+ bitmap->last_total_size= (uint)bytes;
*last_page= ((last_bitmap_page + bytes*8/3));
}
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 371325594af..02cb01b581c 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -3673,7 +3673,7 @@ static my_bool _ma_update_block_record2(MARIA_HA *info,
MARIA_PINNED_PAGE page_link;
uint rownr, org_empty_size, head_length;
uint block_size= info->s->block_size;
- uint errpos= 0;
+ uint errpos __attribute__((unused)) = 0;
uchar *dir;
pgcache_page_no_t page;
struct st_row_pos_info row_pos;
diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c
index 4d60b4cafe5..8e68f5a7898 100644
--- a/storage/maria/ma_check.c
+++ b/storage/maria/ma_check.c
@@ -3940,7 +3940,8 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info,
_ma_check_print_error(param,
"Rows lost (Found %lu of %lu); Aborting "
"because safe repair was requested",
- (ulong) share->state.state.records,
+ (ulong) sort_info.new_info->s->
+ state.state.records,
(ulong) start_records);
share->state.state.records=start_records;
goto err;
@@ -5579,7 +5580,7 @@ static int sort_maria_ft_key_write(MARIA_SORT_PARAM *sort_param,
SORT_KEY_BLOCKS *key_block= sort_info->key_block;
MARIA_SHARE *share= sort_info->info->s;
- val_len=HA_FT_WLEN+share->base.rec_reflength;
+ val_len=HA_FT_WLEN+share->rec_reflength;
get_key_full_length_rdonly(a_len, a);
if (!ft_buf)
@@ -5589,7 +5590,7 @@ static int sort_maria_ft_key_write(MARIA_SORT_PARAM *sort_param,
and row format is NOT static - for _ma_dpointer not to garble offsets
*/
if ((share->base.key_reflength <=
- share->base.rec_reflength) &&
+ share->rec_reflength) &&
(share->options &
(HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)))
ft_buf= (SORT_FT_BUF *)my_malloc(sort_param->keyinfo->block_length +
@@ -5728,8 +5729,8 @@ static int sort_insert_key(MARIA_SORT_PARAM *sort_param,
tmp_key.keyinfo= keyinfo;
tmp_key.data= (uchar*) key;
- tmp_key.data_length= _ma_keylength(keyinfo, key) - share->base.rec_reflength;
- tmp_key.ref_length= share->base.rec_reflength;
+ tmp_key.data_length= _ma_keylength(keyinfo, key) - share->rec_reflength;
+ tmp_key.ref_length= share->rec_reflength;
t_length= (*keyinfo->pack_key)(&tmp_key, nod_flag,
(uchar*) 0, lastkey, lastkey, &s_temp);
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index fa2ee166b7c..069d73b553c 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -243,6 +243,7 @@ my_bool _ma_ck_real_delete(register MARIA_HA *info, MARIA_KEY *key,
if (page.size <= page.node + share->keypage_header + 1)
{
+ DBUG_ASSERT(page.size == page.node + share->keypage_header);
if (page.node)
*root= _ma_kpos(page.node, root_buff +share->keypage_header +
page.node);
@@ -1476,8 +1477,9 @@ my_bool _ma_log_delete(MARIA_PAGE *ma_page, const uchar *key_pos,
MARIA_SHARE *share= info->s;
my_off_t page= ma_page->pos / share->block_size;
DBUG_ENTER("_ma_log_delete");
- DBUG_PRINT("enter", ("page: %lu changed_length: %u move_length: %d",
- (ulong) page, changed_length, move_length));
+ DBUG_PRINT("enter", ("page: %lu offset: %u changed_length: %u move_length: %u append_length: %u page_size: %u",
+ (ulong) page, offset, changed_length, move_length,
+ append_length, ma_page->size));
DBUG_ASSERT(share->now_transactional && move_length);
DBUG_ASSERT(offset + changed_length <= ma_page->size);
DBUG_ASSERT(ma_page->org_size - move_length + append_length == ma_page->size);
diff --git a/storage/maria/ma_ft_nlq_search.c b/storage/maria/ma_ft_nlq_search.c
index 26fd4fcf5eb..e57cc135ca1 100644
--- a/storage/maria/ma_ft_nlq_search.c
+++ b/storage/maria/ma_ft_nlq_search.c
@@ -74,7 +74,7 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio)
uchar *keybuff= aio->keybuff;
MARIA_KEYDEF *keyinfo= info->s->keyinfo+aio->keynr;
my_off_t key_root=info->s->state.key_root[aio->keynr];
- uint extra=HA_FT_WLEN+info->s->base.rec_reflength;
+ uint extra=HA_FT_WLEN+info->s->rec_reflength;
MARIA_KEY key;
#if HA_FT_WTYPE == HA_KEYTYPE_FLOAT
float tmp_weight;
diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c
index 9c794501022..cc1c188e2a2 100644
--- a/storage/maria/ma_key_recover.c
+++ b/storage/maria/ma_key_recover.c
@@ -945,7 +945,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
const uchar *header_end= header + head_length;
uint page_offset= 0, org_page_length;
uint page_length, keypage_header, keynr;
- uint max_page_size= share->max_index_block_size;
+ uint max_page_size= share->max_index_block_size, new_page_length= 0;
int result;
MARIA_PAGE page;
DBUG_ENTER("_ma_apply_redo_index");
@@ -1106,6 +1106,8 @@ uint _ma_apply_redo_index(MARIA_HA *info,
case KEY_OP_DEBUG_2:
DBUG_PRINT("redo", ("org_page_length: %u new_page_length: %u",
uint2korr(header), uint2korr(header+2)));
+ DBUG_ASSERT(uint2korr(header) == page_length);
+ new_page_length= uint2korr(header+2);
header+= 4;
break;
case KEY_OP_MAX_PAGELENGTH:
@@ -1171,6 +1173,7 @@ uint _ma_apply_redo_index(MARIA_HA *info,
}
} while (header < header_end);
DBUG_ASSERT(header == header_end);
+ DBUG_ASSERT(new_page_length == 0 || new_page_length == page_length);
/* Write modified page */
page.size= page_length;
diff --git a/storage/maria/ma_locking.c b/storage/maria/ma_locking.c
index 9bab4cdfe0e..0ec0244bcbd 100644
--- a/storage/maria/ma_locking.c
+++ b/storage/maria/ma_locking.c
@@ -398,7 +398,7 @@ int _ma_mark_file_changed(register MARIA_SHARE *share)
/*
For transactional tables, the table is marked changed when the first page
is written. Here we just mark the state to be updated so that caller
- can do 'anaylze table' and find that is has changed before any pages
+ can do 'analyze table' and find that is has changed before any pages
are written.
*/
if (! test_all_bits(share->state.changed,
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 4814ab23799..801efd3f07c 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -2624,7 +2624,9 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer)
i < buffer->size;
i+= TRANSLOG_PAGE_SIZE, pg++)
{
- TRANSLOG_ADDRESS addr __attribute__((unused))= (buffer->offset + i);
+#ifndef DBUG_OFF
+ TRANSLOG_ADDRESS addr= (buffer->offset + i);
+#endif
DBUG_PRINT("info", ("send log form %lu till %lu address: (%lu,0x%lx) "
"page #: %lu buffer size: %lu buffer: 0x%lx",
(ulong) i, (ulong) (i + TRANSLOG_PAGE_SIZE),
@@ -3327,7 +3329,7 @@ static uint16 translog_get_chunk_header_length(uchar *chunk)
case TRANSLOG_CHUNK_LSN:
{
/* 0 chunk referred as LSN (head or tail) */
- translog_size_t rec_len;
+ translog_size_t rec_len __attribute__((unused));
uchar *start= chunk;
uchar *ptr= start + 1 + 2;
uint16 chunk_len, header_len;
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 82e6e30839b..2b072cc262b 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -756,6 +756,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags)
HA_ERR_CRASHED_ON_REPAIR : HA_ERR_CRASHED_ON_USAGE);
goto err;
}
+ else
+ {
+ /* create_rename_lsn != LSN_NEEDS_NEW_STATE_LSNS */
+ share->state.changed|= STATE_NOT_MOVABLE;
+ }
}
else
share->page_type= PAGECACHE_PLAIN_PAGE;
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index 893e393a79a..f271c17a3af 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -2894,7 +2894,7 @@ static uint end_of_redo_phase(my_bool prepare_for_undo_phase)
static int run_undo_phase(uint uncommitted)
{
- LSN last_undo;
+ LSN last_undo __attribute__((unused));
DBUG_ENTER("run_undo_phase");
if (uncommitted > 0)
@@ -3593,6 +3593,10 @@ my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages)
if (flush_pages)
{
+ /* Ensure that recover is not executing any redo before this */
+ if (!maria_in_recovery)
+ share->state.is_of_horizon= share->state.create_rename_lsn=
+ share->state.skip_redo_lsn= translog_get_horizon();
/*
We are going to change callbacks; if a page is flushed at this moment
this can cause race conditions, that's one reason to flush pages
diff --git a/storage/maria/ma_rt_index.c b/storage/maria/ma_rt_index.c
index 2c2090bf343..79ae751f3ff 100644
--- a/storage/maria/ma_rt_index.c
+++ b/storage/maria/ma_rt_index.c
@@ -1258,7 +1258,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_write.c b/storage/maria/ma_write.c
index 60693d2173a..c6d7ed9ea84 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -373,9 +373,11 @@ err:
else
{
MARIA_KEY key;
- if (_ma_ck_delete(info,
- (*keyinfo->make_key)(info, &key, i, buff, record,
- filepos, info->trn->trid)))
+ if (keyinfo->ck_delete(info,
+ (*keyinfo->make_key)(info, &key, i, buff,
+ record,
+ filepos,
+ info->trn->trid)))
{
if (local_lock_tree)
mysql_rwlock_unlock(&keyinfo->root_lock);
@@ -842,7 +844,7 @@ int _ma_insert(register MARIA_HA *info, MARIA_KEY *key,
{
if (share->max_index_block_size - a_length < 32 &&
(keyinfo->flag & HA_FULLTEXT) && key_pos == endpos &&
- share->base.key_reflength <= share->base.rec_reflength &&
+ share->base.key_reflength <= share->rec_reflength &&
share->options & (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD))
{
/*
diff --git a/storage/maria/unittest/ma_test_recovery.expected b/storage/maria/unittest/ma_test_recovery.expected
index 5f7dd54e673..6a6051735c5 100644
--- a/storage/maria/unittest/ma_test_recovery.expected
+++ b/storage/maria/unittest/ma_test_recovery.expected
@@ -70,7 +70,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -79,7 +79,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -88,7 +88,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -99,7 +99,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -108,7 +108,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -117,7 +117,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -167,7 +167,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -176,7 +176,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -185,7 +185,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -196,7 +196,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -205,7 +205,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -214,7 +214,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -264,7 +264,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -273,7 +273,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -282,7 +282,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -293,7 +293,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -302,7 +302,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -311,7 +311,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -361,7 +361,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -370,7 +370,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -379,7 +379,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -390,7 +390,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -399,7 +399,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -408,7 +408,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -458,7 +458,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -467,7 +467,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -476,7 +476,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -487,7 +487,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -496,7 +496,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -505,7 +505,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -555,7 +555,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -564,7 +564,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -573,7 +573,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -584,7 +584,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -593,7 +593,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -602,7 +602,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -652,7 +652,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -661,7 +661,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -670,7 +670,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -681,7 +681,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -690,7 +690,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -699,7 +699,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -749,7 +749,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -758,7 +758,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -767,7 +767,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -778,7 +778,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -787,7 +787,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -796,7 +796,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -846,7 +846,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -855,7 +855,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -864,7 +864,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -875,7 +875,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -884,7 +884,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -893,7 +893,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -943,7 +943,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -952,7 +952,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -961,7 +961,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -972,7 +972,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -981,7 +981,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -990,7 +990,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1040,7 +1040,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1049,7 +1049,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1058,7 +1058,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1069,7 +1069,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1078,7 +1078,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1087,7 +1087,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1137,7 +1137,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1146,7 +1146,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1155,7 +1155,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1166,7 +1166,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1175,7 +1175,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1184,7 +1184,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1234,7 +1234,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1243,7 +1243,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1252,7 +1252,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1263,7 +1263,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1272,7 +1272,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1281,7 +1281,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1331,7 +1331,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1340,7 +1340,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1349,7 +1349,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1360,7 +1360,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1369,7 +1369,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1378,7 +1378,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1428,7 +1428,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1437,7 +1437,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1446,7 +1446,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1457,7 +1457,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1466,7 +1466,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1475,7 +1475,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1525,7 +1525,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1534,7 +1534,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1543,7 +1543,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1554,7 +1554,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1563,7 +1563,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
@@ -1572,7 +1572,7 @@ applying log
Differences in aria_chk -dvv, recovery not yet perfect !
========DIFF START=======
6c6
-< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled,movable
+< Status: checked,analyzed,optimized keys,sorted index pages,zerofilled
---
> Status: changed
========DIFF END=======
diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c
index 97ab2a6434e..6b36891ccf6 100644
--- a/storage/myisam/ft_nlq_search.c
+++ b/storage/myisam/ft_nlq_search.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2001, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/ft_stopwords.c b/storage/myisam/ft_stopwords.c
index 9eb8b68bf13..8f6f9308d3c 100644
--- a/storage/myisam/ft_stopwords.c
+++ b/storage/myisam/ft_stopwords.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/fulltext.h b/storage/myisam/fulltext.h
index f3fda334472..98b3247ba19 100644
--- a/storage/myisam/fulltext.h
+++ b/storage/myisam/fulltext.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 8fde949189b..86d80b14ce5 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1074,6 +1074,18 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
mi_get_mask_all_keys_active(share->base.keys) :
share->state.key_map);
ulonglong testflag= param.testflag;
+#ifdef HAVE_MMAP
+ bool remap= test(share->file_map);
+ /*
+ mi_repair*() functions family use file I/O even if memory
+ mapping is available.
+
+ Since mixing mmap I/O and file I/O may cause various artifacts,
+ memory mapping must be disabled.
+ */
+ if (remap)
+ mi_munmap_file(file);
+#endif
if (mi_test_if_sort_rep(file,file->state->records,key_map,0) &&
(local_testflag & T_REP_BY_SORT))
{
@@ -1106,6 +1118,10 @@ int ha_myisam::repair(THD *thd, HA_CHECK &param, bool do_optimize)
test(param.testflag & T_QUICK));
}
param.testflag= testflag | (param.testflag & T_RETRY_WITHOUT_QUICK);
+#ifdef HAVE_MMAP
+ if (remap)
+ mi_dynmap_file(file, file->state->data_file_length);
+#endif
optimize_done=1;
}
if (!error)
diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h
index c3c236ad4fe..7439ea290c6 100644
--- a/storage/myisam/ha_myisam.h
+++ b/storage/myisam/ha_myisam.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 05fd9af9079..04d2263ab5b 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 7c7f11ddf78..d4cc31368dd 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_delete_all.c b/storage/myisam/mi_delete_all.c
index 5e9cb26c0ad..37fdf2dcb04 100644
--- a/storage/myisam/mi_delete_all.c
+++ b/storage/myisam/mi_delete_all.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -62,11 +63,6 @@ int mi_delete_all_rows(MI_INFO *info)
mysql_file_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)))
goto err;
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
-#ifdef HAVE_MMAP
- /* Map again */
- if (share->file_map)
- mi_dynmap_file(info, (my_off_t) 0);
-#endif
DBUG_RETURN(0);
err:
diff --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c
index b6530334dd2..885990ee1be 100644
--- a/storage/myisam/mi_delete_table.c
+++ b/storage/myisam/mi_delete_table.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c
index 7a86ff63136..009a2affe0c 100644
--- a/storage/myisam/mi_dynrec.c
+++ b/storage/myisam/mi_dynrec.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c
index c3dd9cb6645..92d7459dfc5 100644
--- a/storage/myisam/mi_extra.c
+++ b/storage/myisam/mi_extra.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index 824855a0211..663a226d850 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 5c89120c156..305984ee94d 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_page.c b/storage/myisam/mi_page.c
index 868b28315c4..bbcacd35d5d 100644
--- a/storage/myisam/mi_page.c
+++ b/storage/myisam/mi_page.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_range.c b/storage/myisam/mi_range.c
index 9d40d1a25c4..2074c873979 100644
--- a/storage/myisam/mi_range.c
+++ b/storage/myisam/mi_range.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_rnext.c b/storage/myisam/mi_rnext.c
index 17cd708cd3c..ee5c74f8da1 100644
--- a/storage/myisam/mi_rnext.c
+++ b/storage/myisam/mi_rnext.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index 6011cbe29c2..968cb9624a6 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c
index e048a83d3f0..3b2597eb01e 100644
--- a/storage/myisam/mi_test1.c
+++ b/storage/myisam/mi_test1.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index 9270ee4fbb8..3ec12ef5cca 100644
--- a/storage/myisam/mi_test2.c
+++ b/storage/myisam/mi_test2.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_unique.c b/storage/myisam/mi_unique.c
index 6df4c07ee0d..cdf3e618275 100644
--- a/storage/myisam/mi_unique.c
+++ b/storage/myisam/mi_unique.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_update.c b/storage/myisam/mi_update.c
index 66193ea1673..b75bd4bf2aa 100644
--- a/storage/myisam/mi_update.c
+++ b/storage/myisam/mi_update.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c
index f00238347ae..70cc96d0cba 100644
--- a/storage/myisam/mi_write.c
+++ b/storage/myisam/mi_write.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/myisam_ftdump.c b/storage/myisam/myisam_ftdump.c
index cb09c3d20dd..ce0d7be3f0b 100644
--- a/storage/myisam/myisam_ftdump.c
+++ b/storage/myisam/myisam_ftdump.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2001, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 981ae61fe9d..32d39e5a09d 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index 222097146fc..a72b329a4c0 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c
index c09e0091a56..3314f1b94ac 100644
--- a/storage/myisam/myisamlog.c
+++ b/storage/myisam/myisamlog.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index 851f5bda700..5d6b03ff4b8 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/rt_index.c b/storage/myisam/rt_index.c
index 48eb48cc5e8..c26dba92823 100644
--- a/storage/myisam/rt_index.c
+++ b/storage/myisam/rt_index.c
@@ -1028,7 +1028,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/rt_split.c b/storage/myisam/rt_split.c
index 48f9b82a0b5..9ab0bd99201 100644
--- a/storage/myisam/rt_split.c
+++ b/storage/myisam/rt_split.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2002, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index da65ddb7be6..6da2c5c7816 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisam/sp_test.c b/storage/myisam/sp_test.c
index cf4519a7734..d573d96086e 100644
--- a/storage/myisam/sp_test.c
+++ b/storage/myisam/sp_test.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 05cd1616dc2..e6bece5b7ff 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h
index 5ebe6c56ca5..e0dc6e07542 100644
--- a/storage/myisammrg/ha_myisammrg.h
+++ b/storage/myisammrg/ha_myisammrg.h
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/myisammrg/myrg_open.c b/storage/myisammrg/myrg_open.c
index 4f1294b0e89..f4fae824650 100644
--- a/storage/myisammrg/myrg_open.c
+++ b/storage/myisammrg/myrg_open.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/storage/pbxt/src/cache_xt.cc b/storage/pbxt/src/cache_xt.cc
index 090250dd802..7f39c589f7a 100644
--- a/storage/pbxt/src/cache_xt.cc
+++ b/storage/pbxt/src/cache_xt.cc
@@ -794,7 +794,7 @@ xtPublic void xt_ind_check_cache(XTIndexPtr ind)
ASSERT_NS(ind_cac_globals.cg_free_count == free_count);
/* Check the LRU list: */
- XTIndBlockPtr list_block, plist_block;
+ XTIndBlockPtr list_block, plist_block __attribute__((unused));
plist_block = NULL;
list_block = ind_cac_globals.cg_lru_block;
diff --git a/storage/pbxt/src/lock_xt.h b/storage/pbxt/src/lock_xt.h
index 28737478d48..002636e3ffa 100644
--- a/storage/pbxt/src/lock_xt.h
+++ b/storage/pbxt/src/lock_xt.h
@@ -67,9 +67,9 @@ inline void xt_atomic_inc1(volatile xtWord1 *mptr)
#elif defined(XT_ATOMIC_GNUC_X86)
xtWord1 val;
- asm volatile ("movb %1,%0" : "=r" (val) : "m" (*mptr) : "memory");
+ asm volatile ("movb %1,%0" : "=q" (val) : "m" (*mptr) : "memory");
val++;
- asm volatile ("xchgb %1,%0" : "=r" (val) : "m" (*mptr), "0" (val) : "memory");
+ asm volatile ("xchgb %1,%0" : "=q" (val) : "m" (*mptr), "0" (val) : "memory");
#elif defined(XT_ATOMIC_SOLARIS_LIB)
atomic_inc_8(mptr);
#else
@@ -91,9 +91,9 @@ inline xtWord1 xt_atomic_dec1(volatile xtWord1 *mptr)
#elif defined(XT_ATOMIC_GNUC_X86)
xtWord1 val2;
- asm volatile ("movb %1, %0" : "=r" (val) : "m" (*mptr) : "memory");
+ asm volatile ("movb %1, %0" : "=q" (val) : "m" (*mptr) : "memory");
val--;
- asm volatile ("xchgb %1,%0" : "=r" (val2) : "m" (*mptr), "0" (val) : "memory");
+ asm volatile ("xchgb %1,%0" : "=q" (val2) : "m" (*mptr), "0" (val) : "memory");
/* Should work, but compiler makes a mistake?
* asm volatile ("xchgb %1, %0" : : "r" (val), "m" (*mptr) : "memory");
*/
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index c3d85a77f3c..41b61be0b5b 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -3486,7 +3486,7 @@ skip_info:
}
if (page_is_corrupt) {
- fprintf(stderr, " [errp:%lld]", offset / (zip_size ? zip_size : UNIV_PAGE_SIZE));
+ fprintf(stderr, " [errp:%ld]", (long)(offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)));
/* cannot treat corrupt page */
goto skip_write;
@@ -3499,8 +3499,8 @@ skip_info:
if (offset / (zip_size ? zip_size : UNIV_PAGE_SIZE) == root_page[i]) {
if (fil_page_get_type(page) != FIL_PAGE_INDEX) {
file_is_corrupt = TRUE;
- fprintf(stderr, " [etyp:%lld]",
- offset / (zip_size ? zip_size : UNIV_PAGE_SIZE));
+ fprintf(stderr, " [etyp:%ld]",
+ (long)(offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)));
goto skip_write;
}
/* this is index root page */
@@ -3729,7 +3729,6 @@ func_exit:
ulint page_no;
ulint zip_size;
ulint height;
- ulint root_height = 0;
rec_t* node_ptr;
dict_table_t* table;
dict_index_t* index;
@@ -3768,7 +3767,6 @@ func_exit:
if (height == ULINT_UNDEFINED) {
height = btr_page_get_level(page, &mtr);
- root_height = height;
}
if (height == 0) {
@@ -4159,7 +4157,7 @@ fil_load_single_table_tablespace(
size = (((ib_uint64_t)size_high) << 32) + (ib_uint64_t)size_low;
#ifndef UNIV_HOTBACKUP
- if (size < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
+ if (size < (ib_uint64_t)FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Error: the size of single-table tablespace"
" file %s\n"
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index f3f2100389c..b706523596f 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -3127,7 +3127,7 @@ innobase_commit_low(
#ifdef MYSQL_SERVER
THD *thd=current_thd;
- if (thd && thd->slave_thread) {
+ if (thd && thd_is_replication_slave_thread(thd)) {
/* Update the replication position info inside InnoDB.
In embedded server, does nothing. */
const char *log_file_name, *group_relay_log_name;
@@ -6023,14 +6023,15 @@ calc_row_difference(
/* The field has changed */
ufield = uvect->fields + n_changed;
+ UNIV_MEM_INVALID(ufield, sizeof *ufield);
/* Let us use a dummy dfield to make the conversion
from the MySQL column format to the InnoDB format */
- dict_col_copy_type(prebuilt->table->cols + innodb_idx,
- dfield_get_type(&dfield));
-
if (n_len != UNIV_SQL_NULL) {
+ dict_col_copy_type(prebuilt->table->cols + innodb_idx,
+ dfield_get_type(&dfield));
+
buf = row_mysql_store_col_in_innobase_format(
&dfield,
(byte*)buf,
@@ -6038,7 +6039,7 @@ calc_row_difference(
new_mysql_row_col,
col_pack_len,
dict_table_is_comp(prebuilt->table));
- dfield_copy_data(&ufield->new_val, &dfield);
+ dfield_copy(&ufield->new_val, &dfield);
} else {
dfield_set_null(&ufield->new_val);
}
@@ -11561,7 +11562,7 @@ ha_innobase::check_if_incompatible_data(
if (info_row_type == ROW_TYPE_DEFAULT)
info_row_type = ROW_TYPE_COMPACT;
if ((info->used_fields & HA_CREATE_USED_ROW_FORMAT) &&
- get_row_type() != ((info->row_type == ROW_TYPE_DEFAULT)
+ row_type != ((info->row_type == ROW_TYPE_DEFAULT)
? ROW_TYPE_COMPACT : info->row_type)) {
DBUG_PRINT("info", ("get_row_type()=%d != info->row_type=%d -> "
@@ -12370,15 +12371,12 @@ static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
NULL, NULL, 500L, 1L, ~0L, 0);
#ifdef EXTENDED_FOR_KILLIDLE
-#define TMP_STR "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB."
+#define kill_idle_help_text "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB."
#else
-#define TMP_STR "No effect for this build."
+#define kill_idle_help_text "No effect for this build."
#endif
-static MYSQL_SYSVAR_ULONG(kill_idle_transaction, srv_kill_idle_transaction,
- PLUGIN_VAR_RQCMDARG,
- TMP_STR,
- NULL, NULL, 0, 0, LONG_MAX, 0);
-#undef TMP_STR
+static MYSQL_SYSVAR_LONGLONG(kill_idle_transaction, srv_kill_idle_transaction,
+ PLUGIN_VAR_RQCMDARG, kill_idle_help_text, NULL, NULL, 0, 0, LONG_MAX, 0);
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 0c864a265e0..6f985eacdf3 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -299,7 +299,7 @@ extern ibool srv_print_latch_waits;
extern ulint srv_activity_count;
extern ulint srv_fatal_semaphore_wait_threshold;
extern ulint srv_dml_needed_delay;
-extern ulong srv_kill_idle_transaction;
+extern long long srv_kill_idle_transaction;
extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
query threads, and lock table: we allocate
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index 8fe8bab5d9a..ea7abb2549e 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -334,6 +334,8 @@ os_aio_validate_skip(void)
#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
@@ -3518,9 +3520,10 @@ os_aio_init(
os_last_printout = time(NULL);
#ifdef _WIN32
- ut_a(completion_port == 0);
+ ut_a(completion_port == 0 && read_completion_port == 0);
completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
- ut_a(completion_port);
+ read_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
+ ut_a(completion_port && read_completion_port);
#endif
return(TRUE);
@@ -3571,6 +3574,7 @@ os_aio_array_wake_win_aio_at_shutdown(
if(completion_port)
{
PostQueuedCompletionStatus(completion_port, 0, IOCP_SHUTDOWN_KEY, NULL);
+ PostQueuedCompletionStatus(read_completion_port, 0, IOCP_SHUTDOWN_KEY, NULL);
}
}
#endif
@@ -4244,6 +4248,9 @@ err_exit:
}
#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
@@ -4282,18 +4289,45 @@ os_aio_windows_handle(
DWORD len;
BOOL retry = FALSE;
ULONG_PTR key;
+ HANDLE port = READ_SEGMENT(segment)? read_completion_port : completion_port;
- ret = GetQueuedCompletionStatus(completion_port, &len, &key,
- (OVERLAPPED **)&slot, INFINITE);
+ for(;;) {
+ ret = GetQueuedCompletionStatus(port, &len, &key,
+ (OVERLAPPED **)&slot, INFINITE);
- /* If shutdown key was received, repost the shutdown message and exit */
- if (ret && (key == IOCP_SHUTDOWN_KEY)) {
- PostQueuedCompletionStatus(completion_port, 0, key, NULL);
- os_thread_exit(NULL);
- }
+ /* 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);
+ }
+
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ os_thread_exit(NULL);
+ }
- if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
- os_thread_exit(NULL);
+ 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;
+ }
}
*message1 = slot->message1;
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index da035421ab9..9bda27e4b1f 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -496,6 +496,8 @@ row_ins_cascade_calc_update_vec(
ufield->field_no
= dict_table_get_nth_col_pos(
table, dict_col_get_no(col));
+
+ ufield->orig_len = 0;
ufield->exp = NULL;
ufield->new_val = parent_ufield->new_val;
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index 589f632ff5b..0c07d75b39a 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -104,7 +104,7 @@ UNIV_INTERN ulint srv_activity_count = 0;
UNIV_INTERN ulint srv_fatal_semaphore_wait_threshold = 600;
/**/
-UNIV_INTERN ulong srv_kill_idle_transaction = 0;
+UNIV_INTERN long long srv_kill_idle_transaction = 0;
/* How much data manipulation language (DML) statements need to be delayed,
in microseconds, in order to reduce the lagging of the purge thread. */
diff --git a/strings/CMakeLists.txt b/strings/CMakeLists.txt
index 8d35c732333..2747374058d 100644
--- a/strings/CMakeLists.txt
+++ b/strings/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2010, Oracle and/or its affiliates
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
diff --git a/strings/conf_to_src.c b/strings/conf_to_src.c
index aebeafcda98..7dfc76e5417 100644
--- a/strings/conf_to_src.c
+++ b/strings/conf_to_src.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2000-2003, 2005-2007 MySQL AB, 2009 Sun Microsystems, Inc.
+ Copyright (c) 2009-2011, Monty Program Ab
Use is subject to license terms.
Copyright (c) 2009-2011, Monty Program Ab
diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c
index 1b8e2fb5f3a..7c7d8c7b2f5 100644
--- a/strings/ctype-big5.c
+++ b/strings/ctype-big5.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* 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
diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c
index 8f09561fb16..d28d576c661 100644
--- a/strings/ctype-bin.c
+++ b/strings/ctype-bin.c
@@ -1,5 +1,4 @@
-/* Copyright tommy@valley.ne.jp.
- Copyright (c) 2002, 2011, Oracle and/or its affiliates.
+/* Copyright (c) 2002-2007 MySQL AB & tommy@valley.ne.jp
Copyright (c) 2009-2011, Monty Program Ab
This library is free software; you can redistribute it and/or
diff --git a/strings/ctype-cp932.c b/strings/ctype-cp932.c
index ffab57a7d96..b7847e4509e 100644
--- a/strings/ctype-cp932.c
+++ b/strings/ctype-cp932.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates.
+/* 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
diff --git a/strings/ctype-czech.c b/strings/ctype-czech.c
index 08c8412e8ae..36fc6b36f0c 100644
--- a/strings/ctype-czech.c
+++ b/strings/ctype-czech.c
@@ -1,5 +1,6 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2000-2007 MySQL AB
Copyright (c) 2009-2011, Monty Program Ab
+ Use is subject to license terms.
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
diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c
index 77296f34f6a..3caa1977c0b 100644
--- a/strings/ctype-euc_kr.c
+++ b/strings/ctype-euc_kr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* 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
diff --git a/strings/ctype-extra.c b/strings/ctype-extra.c
index b52cc603e4d..e0499c6f2e3 100644
--- a/strings/ctype-extra.c
+++ b/strings/ctype-extra.c
@@ -6,7 +6,8 @@
./conf_to_src ../sql/share/charsets/ > FILE
*/
-/* Copyright (c) 2003, 2010, Oracle and/or its affiliates.
+/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc.
+ Copyright (c) 2000, 2011, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c
index af6c6f9f8c2..b27ea67059d 100644
--- a/strings/ctype-gb2312.c
+++ b/strings/ctype-gb2312.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* 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
diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c
index 601bbabddb5..8b37de4a5e7 100644
--- a/strings/ctype-gbk.c
+++ b/strings/ctype-gbk.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* 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
diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c
index f5456c1a943..80ae11c82c2 100644
--- a/strings/ctype-latin1.c
+++ b/strings/ctype-latin1.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2000, 2003-2007 MySQL AB, 2009 Sun Microsystems, Inc.
- Use is subject to license terms.
Copyright (c) 2009-2011, Monty Program Ab
+ Use is subject to license terms.
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
diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c
index 33e0c58cbbf..5879bdf7978 100644
--- a/strings/ctype-mb.c
+++ b/strings/ctype-mb.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* 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
diff --git a/strings/ctype-simple.c b/strings/ctype-simple.c
index eb8c44805da..e60f9307e39 100644
--- a/strings/ctype-simple.c
+++ b/strings/ctype-simple.c
@@ -1,5 +1,6 @@
-/* Copyright (c) 2002, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2002-2007 MySQL AB, 2009 Sun Microsystems, Inc.
Copyright (c) 2009-2011, Monty Program Ab
+ Use is subject to license terms.
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
diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c
index 042ceab4f35..50756799a56 100644
--- a/strings/ctype-sjis.c
+++ b/strings/ctype-sjis.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* 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
diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c
index f6fe4c0f914..d97f8e5ff08 100644
--- a/strings/ctype-tis620.c
+++ b/strings/ctype-tis620.c
@@ -1,20 +1,5 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* 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.
-
- 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 */
-
-/*
Copyright (C) 2003 by Sathit Jittanupat
<jsat66@hotmail.com,jsat66@yahoo.com>
* solving bug crash with long text field string
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c
index b5f151c4d10..7dc1527002f 100644
--- a/strings/ctype-uca.c
+++ b/strings/ctype-uca.c
@@ -1,5 +1,6 @@
-/* Copyright (c) 2004, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2004-2007 MySQL AB, 2009 Sun Microsystems, Inc.
Copyright (c) 2009-2011, Monty Program Ab
+ Use is subject to license terms.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c
index b22ca43a062..a780a296a9b 100644
--- a/strings/ctype-ucs2.c
+++ b/strings/ctype-ucs2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2003, 2010, Oracle and/or its affiliates
Copyright (c) 2009-2011, Monty Program Ab
This library is free software; you can redistribute it and/or
diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c
index 32d65a07f23..ecb0992c70d 100644
--- a/strings/ctype-ujis.c
+++ b/strings/ctype-ujis.c
@@ -1,5 +1,5 @@
/* Copyright tommy@valley.ne.jp.
- Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2002, 2011, Oracle and/or its affiliates.
Copyright (c) 2009-2011, Monty Program Ab
This library is free software; you can redistribute it and/or
diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c
index daca63437ca..81198147363 100644
--- a/strings/ctype-utf8.c
+++ b/strings/ctype-utf8.c
@@ -1,5 +1,6 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2002-2008 MySQL AB, 2009 Sun Microsystems, Inc.
Copyright (c) 2009-2011, Monty Program Ab
+ Use is subject to license terms.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
diff --git a/strings/ctype-win1250ch.c b/strings/ctype-win1250ch.c
index a22fe7b696f..8fd15ebddb2 100644
--- a/strings/ctype-win1250ch.c
+++ b/strings/ctype-win1250ch.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2001 Jan Pazdziora.
- Copyright (c) 2002, 2010, Oracle and/or its affiliates.
+ Copyright (c) 2002-2007 MySQL AB
Copyright (c) 2009-2011, Monty Program Ab
This program is free software; you can redistribute it and/or modify
diff --git a/strings/ctype.c b/strings/ctype.c
index 296960b55b5..6b6983ada60 100644
--- a/strings/ctype.c
+++ b/strings/ctype.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2000-2007 MySQL AB, 2008, 2009 Sun Microsystems, Inc.
+ Copyright (c) 2009-2011, Monty Program Ab
Use is subject to license terms.
Copyright (c) 2009-2011, Monty Program Ab
diff --git a/strings/decimal.c b/strings/decimal.c
index 8ac3d61612d..c0021da6570 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1474,9 +1474,8 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
{
int frac0=scale>0 ? ROUND_UP(scale) : scale/DIG_PER_DEC1,
frac1=ROUND_UP(from->frac), UNINIT_VAR(round_digit),
- intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len,
- intg1=ROUND_UP(from->intg +
- (((intg0 + frac0)>0) && (from->buf[0] == DIG_MAX)));
+ intg0=ROUND_UP(from->intg), error=E_DEC_OK, len=to->len;
+
dec1 *buf0=from->buf, *buf1=to->buf, x, y, carry=0;
int first_dig;
@@ -1491,6 +1490,12 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
default: DBUG_ASSERT(0);
}
+ /*
+ For my_decimal we always use len == DECIMAL_BUFF_LENGTH == 9
+ For internal testing here (ifdef MAIN) we always use len == 100/4
+ */
+ DBUG_ASSERT(from->len == to->len);
+
if (unlikely(frac0+intg0 > len))
{
frac0=len-intg0;
@@ -1504,17 +1509,17 @@ decimal_round(const decimal_t *from, decimal_t *to, int scale,
return E_DEC_OK;
}
- if (to != from || intg1>intg0)
+ if (to != from)
{
dec1 *p0= buf0+intg0+max(frac1, frac0);
- dec1 *p1= buf1+intg1+max(frac1, frac0);
+ dec1 *p1= buf1+intg0+max(frac1, frac0);
+
+ DBUG_ASSERT(p0 - buf0 <= len);
+ DBUG_ASSERT(p1 - buf1 <= len);
while (buf0 < p0)
*(--p1) = *(--p0);
- if (unlikely(intg1 > intg0))
- to->buf[0]= 0;
- intg0= intg1;
buf0=to->buf;
buf1=to->buf;
to->sign=from->sign;
diff --git a/strings/do_ctype.c b/strings/do_ctype.c
index addb3a3d7f6..55e319a2295 100644
--- a/strings/do_ctype.c
+++ b/strings/do_ctype.c
@@ -1,5 +1,6 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2000-2002, 2006, 2007 MySQL AB
Copyright (c) 2009-2011, Monty Program Ab
+ Use is subject to license terms.
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
diff --git a/strings/dump_map.c b/strings/dump_map.c
index 83d35f259a1..debc44d6f5f 100644
--- a/strings/dump_map.c
+++ b/strings/dump_map.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2003, 2004, 2006 MySQL AB
+ Copyright (c) 2009-2011, Monty Program Ab
Use is subject to license terms.
Copyright (c) 2009-2011, Monty Program Ab
diff --git a/strings/my_strchr.c b/strings/my_strchr.c
index 9bb1f0954ed..0305ef89542 100644
--- a/strings/my_strchr.c
+++ b/strings/my_strchr.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2005, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2005, 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
diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c
index dde6b0255ed..8d8c078849c 100644
--- a/strings/my_vsnprintf.c
+++ b/strings/my_vsnprintf.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2010, Oracle and/or its affiliates.
+/* 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
diff --git a/strings/str_alloc.c b/strings/str_alloc.c
index 3e218ff1fbd..17139e7b773 100644
--- a/strings/str_alloc.c
+++ b/strings/str_alloc.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2005, 2006 MySQL AB
+/* Copyright (c) 2005, 2006 MySQL AB
+ Copyright (c) 2009-2011, Monty Program Ab
Use is subject to license terms.
Copyright (c) 2009-2011, Monty Program Ab
diff --git a/strings/strappend.c b/strings/strappend.c
index 29d38e74fb5..2d04f009a60 100644
--- a/strings/strappend.c
+++ b/strings/strappend.c
@@ -26,6 +26,16 @@
SUCH DAMAGE.
*/
+/* File : strappend.c
+ Author : Monty
+ Updated: 1987.02.07
+ Defines: strappend()
+
+ strappend(dest, len, fill) appends fill-characters to a string so that
+ the result length == len. If the string is longer than len it's
+ trunked. The des+len character is allways set to NULL.
+*/
+
#include "strings_def.h"
void strappend(register char *s, size_t len, pchar fill)
diff --git a/strings/strcend.c b/strings/strcend.c
index 35f103fc40a..55b05bfcefa 100644
--- a/strings/strcend.c
+++ b/strings/strcend.c
@@ -26,6 +26,15 @@
SUCH DAMAGE.
*/
+/* File : strcend.c
+ Author : Michael Widenius: ifdef MC68000
+ Updated: 20 April 1984
+ Defines: strcend()
+
+ strcend(s, c) returns a pointer to the first place in s where c
+ occurs, or a pointer to the end-null of s if c does not occur in s.
+*/
+
#include "strings_def.h"
char *strcend(register const char *s, register pchar c)
diff --git a/strings/strmake.c b/strings/strmake.c
index b6f37dd3d88..951a589e360 100644
--- a/strings/strmake.c
+++ b/strings/strmake.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2000, 2001, 2003, 2006-2008 MySQL AB, 2009 Sun Microsystems, Inc.
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates.
+ Copyright (c) 2009-2011, Monty Program Ab
Use is subject to license terms.
Copyright (c) 2009-2011, Monty Program Ab
diff --git a/strings/uca-dump.c b/strings/uca-dump.c
index ab3437d17df..d5c20854636 100644
--- a/strings/uca-dump.c
+++ b/strings/uca-dump.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2004, 2006 MySQL AB
+ Copyright (c) 2009-2011, Monty Program Ab
Use is subject to license terms.
Copyright (c) 2009-2011, Monty Program Ab
diff --git a/strings/utr11-dump.c b/strings/utr11-dump.c
index 8bd5e9ee58b..0806b3ba0cd 100644
--- a/strings/utr11-dump.c
+++ b/strings/utr11-dump.c
@@ -1,4 +1,5 @@
/* Copyright (c) 2004, 2006 MySQL AB
+ Copyright (c) 2009-2011, Monty Program Ab
Use is subject to license terms.
Copyright (c) 2009-2011, Monty Program Ab
diff --git a/support-files/compiler_warnings.supp b/support-files/compiler_warnings.supp
index e4c39b0c548..1168770d624 100644
--- a/support-files/compiler_warnings.supp
+++ b/support-files/compiler_warnings.supp
@@ -189,6 +189,7 @@ ctype-simple\.c : .*unary minus operator applied to unsigned type, result still
regexec\.c : passing argument 3 of.*matcher.* discards qualifiers from pointer target type
libmysql\.c: passing argument 2 of .*memcpy.* discards qualifiers from pointer target type : 3000-4000
storage/xtradb/dict/dict0dict\.c : passing argument 1 of .*strcpy.* discards qualifiers from pointer target type : 2500-3500
+storage/xtradb/sync/sync0rw\.c : passing argument 1 of .*memset.* discards qualifiers from pointer target type : 200-300
#
# Strange things from autoconf that is probably safe to ignore
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index d62220e2aa8..4c1d30724a0 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -1,5 +1,5 @@
-/* Copyright (c) 2002, 2010, Oracle and/or its affiliates.
- Copyright (c) 2011 Monty Program Ab
+/* Copyright (c) 2002, 2011, Oracle and/or its affiliates.
+ 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
@@ -19803,6 +19803,88 @@ static void test_bug11754979()
/*
+ Bug#13001491: MYSQL_REFRESH CRASHES WHEN STORED ROUTINES ARE RUN
+ CONCURRENTLY.
+*/
+
+static void test_bug13001491()
+{
+ int rc;
+ char query[MAX_TEST_QUERY_LENGTH];
+ MYSQL *c;
+
+ myheader("test_bug13001491");
+
+ my_snprintf(query, MAX_TEST_QUERY_LENGTH,
+ "GRANT ALL PRIVILEGES ON *.* TO mysqltest_u1@%s",
+ opt_host ? opt_host : "'localhost'");
+
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+
+ my_snprintf(query, MAX_TEST_QUERY_LENGTH,
+ "GRANT RELOAD ON *.* TO mysqltest_u1@%s",
+ opt_host ? opt_host : "'localhost'");
+
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+
+ c= mysql_client_init(NULL);
+
+ DIE_UNLESS(mysql_real_connect(c, opt_host, "mysqltest_u1", NULL,
+ current_db, opt_port, opt_unix_socket,
+ CLIENT_MULTI_STATEMENTS |
+ CLIENT_MULTI_RESULTS));
+
+ rc= mysql_query(c, "DROP PROCEDURE IF EXISTS p1");
+ myquery(rc);
+
+ rc= mysql_query(c,
+ "CREATE PROCEDURE p1() "
+ "BEGIN "
+ " DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END; "
+ " SELECT COUNT(*) "
+ " FROM INFORMATION_SCHEMA.PROCESSLIST "
+ " GROUP BY user "
+ " ORDER BY NULL "
+ " INTO @a; "
+ "END");
+ myquery(rc);
+
+ rc= mysql_query(c, "CALL p1()");
+ myquery(rc);
+
+ mysql_free_result(mysql_store_result(c));
+
+ /* Check that mysql_refresh() succeeds without REFRESH_LOG. */
+ rc= mysql_refresh(c, REFRESH_GRANT |
+ REFRESH_TABLES | REFRESH_HOSTS |
+ REFRESH_STATUS | REFRESH_THREADS);
+ myquery(rc);
+
+ /*
+ Check that mysql_refresh(REFRESH_LOG) does not crash the server even if it
+ fails. mysql_refresh(REFRESH_LOG) fails when error log points to unavailable
+ location.
+ */
+ mysql_refresh(c, REFRESH_LOG);
+
+ rc= mysql_query(c, "DROP PROCEDURE p1");
+ myquery(rc);
+
+ mysql_close(c);
+ c= NULL;
+
+ my_snprintf(query, MAX_TEST_QUERY_LENGTH,
+ "DROP USER mysqltest_u1@%s",
+ opt_host ? opt_host : "'localhost'");
+
+ rc= mysql_query(mysql, query);
+ myquery(rc);
+}
+
+
+/*
Read and parse arguments and MySQL options from my.cnf
*/
@@ -20148,6 +20230,7 @@ static struct my_tests_st my_tests[]= {
{ "test_bug12337762", test_bug12337762 },
{ "test_progress_reporting", test_progress_reporting },
{ "test_bug11754979", test_bug11754979 },
+ { "test_bug13001491", test_bug13001491 },
{ 0, 0 }
};
diff --git a/unittest/examples/no_plan-t.c b/unittest/examples/no_plan-t.c
index 9aeb5c7666a..b795b2ca655 100644
--- a/unittest/examples/no_plan-t.c
+++ b/unittest/examples/no_plan-t.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/unittest/examples/skip-t.c b/unittest/examples/skip-t.c
index aa105385c17..4b1115e50f3 100644
--- a/unittest/examples/skip-t.c
+++ b/unittest/examples/skip-t.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/unittest/examples/skip_all-t.c b/unittest/examples/skip_all-t.c
index 940d9f0186f..9d31e0c3af8 100644
--- a/unittest/examples/skip_all-t.c
+++ b/unittest/examples/skip_all-t.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/unittest/examples/todo-t.c b/unittest/examples/todo-t.c
index 53aaa1c2813..e1be2e8eacd 100644
--- a/unittest/examples/todo-t.c
+++ b/unittest/examples/todo-t.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/unittest/mysys/bitmap-t.c b/unittest/mysys/bitmap-t.c
index 75250d157e1..4a26b570136 100644
--- a/unittest/mysys/bitmap-t.c
+++ b/unittest/mysys/bitmap-t.c
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/unittest/mytap/t/basic-t.c b/unittest/mytap/t/basic-t.c
index dcb13b20f11..9a909baba96 100644
--- a/unittest/mytap/t/basic-t.c
+++ b/unittest/mytap/t/basic-t.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/*
+ Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/unittest/mytap/tap.h b/unittest/mytap/tap.h
index 535db3e6c6c..55f74f5fa02 100644
--- a/unittest/mytap/tap.h
+++ b/unittest/mytap/tap.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2006, 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/unittest/strings/strings-t.c b/unittest/strings/strings-t.c
index 66b3ac63792..7e61cb8722e 100644
--- a/unittest/strings/strings-t.c
+++ b/unittest/strings/strings-t.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2010, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/vio/viosocket.c b/vio/viosocket.c
index 4772847abd8..9840891b69e 100644
--- a/vio/viosocket.c
+++ b/vio/viosocket.c
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2001, 2011, Oracle and/or its affiliates
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -692,7 +692,9 @@ my_bool vio_is_connected(Vio *vio)
void vio_timeout(Vio *vio, uint which, uint timeout)
{
#if defined(SO_SNDTIMEO) && defined(SO_RCVTIMEO)
+#ifndef DBUG_OFF
int r;
+#endif
DBUG_ENTER("vio_timeout");
{
diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c
index 7c9269de853..f64869e905d 100644
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -284,7 +284,8 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file,
struct st_VioSSLFd *ssl_fd;
int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE;
if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file,
- ca_path, cipher, TLSv1_server_method(), error)))
+ ca_path, cipher,
+ (SSL_METHOD*) TLSv1_server_method(), error)))
{
return 0;
}