merge from mysql-trunk-bugfixing
This commit is contained in:
commit
2fe246329f
@ -20,4 +20,5 @@
|
||||
# #Legacy option, maybe not needed anymore , taken as is from autotools build
|
||||
# ADD_DEFINITIONS(-DNET_RETRY_COUNT=1000000)
|
||||
|
||||
ADD_DEFINITIONS(-DHAVE_BROKEN_REALPATH)
|
||||
# The below was used for really old versions of FreeBSD, roughly: before 5.1.9
|
||||
# ADD_DEFINITIONS(-DHAVE_BROKEN_REALPATH)
|
||||
|
@ -110,6 +110,10 @@ IF(MSVC)
|
||||
ADD_DEFINITIONS(/wd4996)
|
||||
ENDIF()
|
||||
|
||||
# Make class/struct definition mismatch an error (overseen too often,
|
||||
# adds tons of new warnings)
|
||||
ADD_DEFINITIONS(/we4099)
|
||||
|
||||
IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||
# _WIN64 is defined by the compiler itself.
|
||||
# Yet, we define it here again to work around a bug with Intellisense
|
||||
|
@ -1301,9 +1301,7 @@ case $SYSTEM_TYPE in
|
||||
if test "$OSVERSION" -gt "600000"
|
||||
then
|
||||
# Post user-level threads, MYSQLD_NET_RETRY_COUNT is not needed any more
|
||||
AC_MSG_WARN([Adding fix for broken realpath])
|
||||
CFLAGS="$CFLAGS -DHAVE_BROKEN_REALPATH"
|
||||
CXXFLAGS="$CXXFLAGS -DHAVE_BROKEN_REALPATH"
|
||||
:
|
||||
elif test "$OSVERSION" -gt "480100" && \
|
||||
test "$OSVERSION" -lt "500000" || \
|
||||
test "$OSVERSION" -gt "500109"
|
||||
|
@ -3,3 +3,4 @@ perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collection
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_ndb_row --vardir=var-rpl_ndb_row --mysqld=--binlog-format=row --suite=rpl_ndb,ndb
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-ndb
|
||||
|
@ -24,9 +24,10 @@ main.sp @solaris # Bug#47791 2010-01-20 alik Several tes
|
||||
main.type_float @freebsd # Bug#38965 2010-05-04 alik test cases gis-rtree, type_float, type_newdecimal fail in embedded server
|
||||
main.wait_timeout @solaris # Bug#51244 2010-04-26 alik wait_timeout fails on OpenSolaris
|
||||
|
||||
parts.partition_alter4_innodb # Bug#45299 2010-06-28 alik Test "partition_alter4_innodb" is taking too long, timeout
|
||||
perfschema.pfs_upgrade # Bug#53102 2010-06-15 alik perfschema.pfs_upgrade fails on sol10 sparc64 max in parallel mode
|
||||
|
||||
rpl.rpl_heartbeat_basic # BUG#43828 2009-10-22 luis fails sporadically
|
||||
rpl.rpl_heartbeat_basic # BUG#54820 2010-06-26 alik rpl.rpl_heartbeat_basic fails sporadically again
|
||||
rpl.rpl_heartbeat_2slaves # BUG#43828 2009-10-22 luis fails sporadically
|
||||
rpl.rpl_innodb_bug28430* # Bug#46029
|
||||
rpl.rpl_innodb_bug30888* @solaris # Bug#47646 2009-09-25 alik rpl.rpl_innodb_bug30888 fails sporadically on Solaris
|
||||
@ -35,6 +36,7 @@ rpl.rpl_plugin_load* @solaris # Bug#47146
|
||||
rpl.rpl_row_sp011* @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
|
||||
|
||||
sys_vars.max_sp_recursion_depth_func @solaris # Bug#47791 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun
|
||||
sys_vars.slow_query_log_func @solaris # Bug#54819 2010-06-26 alik sys_vars.slow_query_log_func fails sporadically on Solaris 10
|
||||
sys_vars.wait_timeout_func # Bug#41255 2010-04-26 alik wait_timeout_func fails
|
||||
|
||||
# Declare all NDB-tests in ndb and rpl_ndb test suites experimental.
|
||||
|
@ -1,5 +1,5 @@
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental --skip-ndb
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb
|
||||
|
186
mysql-test/collections/disabled-per-push.list
Normal file
186
mysql-test/collections/disabled-per-push.list
Normal file
@ -0,0 +1,186 @@
|
||||
rpl.rpl000010 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl000011 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl000013 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_000015 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_alter_db : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_auto_increment_11932 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_auto_increment_update_failure : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_begin_commit_rollback : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_binlog_grant : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_binlog_query_filter_rules : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_bit : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_bit_npk : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_blackhole : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_bug31076 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_bug33931 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_bug38694 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_bug41902 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_charset : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_concurrency_error : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_create_if_not_exists : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_create_tmp_table_if_not_exists : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_cross_version : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_do_grant : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_drop_if_exists : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_EE_err : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_empty_master_host : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_extraColmaster_myisam : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_extraCol_myisam : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_filter_tables_not_exist : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_flushlog_loop : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_flush_logs : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_foreign_key_innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_free_items : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_get_lock : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_grant : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_heartbeat : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_idempotency : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_ignore_revoke : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_ignore_table_update : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_incident : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_init_slave_errors : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_init_slave : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_innodb_bug30888 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_innodb_mixed_ddl : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_insert_id_pk : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_insert_ignore : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_insert_select : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_ip_mix2 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_ip_mix : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_ipv4_as_ipv6 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_ipv6 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_known_bugs_detection : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_loaddata_charset : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_loaddata_fatal : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_loaddatalocal : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_loaddata : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_loaddata_map : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_loaddata_simple : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_loaddata_s : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_loaddata_symlink : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_log_pos : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_master_pos_wait : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_misc_functions : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_mixed_binlog_max_cache_size : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_mixed_bit_pk : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_mixed_ddl_dml : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_mixed_implicit_commit_binlog : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_mixed_mixing_engines : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_mixed_row_innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_mix_found_rows : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_multi_delete2 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_multi_delete : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_multi_engine : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_multi_update2 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_multi_update3 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_multi_update4 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_multi_update : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_mysql_upgrade : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_name_const : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_nondeterministic_functions : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_non_direct_mixed_mixing_engines : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_non_direct_row_mixing_engines : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_non_direct_stm_mixing_engines : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_not_null_myisam : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_optimize : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_ps : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_relayrotate : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_relay_space_innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_relayspace : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_relay_space_myisam : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_replicate_ignore_db : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_rewrt_db : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_4_bytes : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_basic_2myisam : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_basic_3innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_basic_8partition : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_colSize : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_disabled_slave_key : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_drop : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_flsh_tbls : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_func001 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_func002 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_func003 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_idempotency : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_implicit_commit_binlog : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_inexist_tbl : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_loaddata_concurrent : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_max_relay_size : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_mixing_engines : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_reset_slave : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_show_relaylog_events : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_sp001 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_sp002_innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_sp005 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_sp006_InnoDB : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_sp007_innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_sp008 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_sp009 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_sp012 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_tabledefs_2myisam : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_tabledefs_3innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_trig001 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_trig002 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_trig003 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_trig004 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_trunc_temp : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_unsafe_funcs : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_until : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_USER : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_utf16 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_utf32 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_view01 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_row_wide_table : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_server_id1 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_server_id2 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_server_id_ignore : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_server_id : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_set_charset : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_set_null_innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_set_null_myisam : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_sf : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_skip_error : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_slave_grp_exec : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_slave_load_in : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_slave_load_tmpdir_not_exist : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_slave_status : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_slow_query_log : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_sp004 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_sporadic_master : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_000001 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_auto_increment_bug33029 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_binlog_max_cache_size : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_conflicts : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_EE_err2 : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_flsh_tbls : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_found_rows : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_insert_delayed : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_loaddata_concurrent : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_loadfile : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_log : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_max_relay_size : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_mixing_engines : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_mix_show_relaylog_events : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_multi_query : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_no_op : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_reset_slave : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_sql_mode : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_start_stop_slave : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_stop_middle_group : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_until : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_stm_user_variables : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_temporary_errors : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_temporary : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_temp_table : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_temp_table_mix_row : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_temp_temporary : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_truncate_2myisam : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_truncate_3innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_trunc_temp : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_typeconv_innodb : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_typeconv : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_user : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_user_variables : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_variables : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
||||
rpl.rpl_variables_stm : lsoares 2010-05-26 WL#5408 Reduce Pushbuild2 turnaround times for rpl suite.
|
@ -1,5 +1,5 @@
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-test-list=collections/disabled-per-push.list
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
|
||||
|
@ -1,5 +1,5 @@
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema --skip-test-list=collections/disabled-per-push.list
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-emebbed --embedded --suite=main,binlog,innodb,federated,rpl,sys_vars,perfschema
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --mysqld=--binlog-format=row --suite=rpl,binlog --skip-test-list=collections/disabled-per-push.list
|
||||
perl mysql-test-run.pl --timer --force --parallel=auto --experimental=collections/default.experimental --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1
|
||||
|
@ -104,10 +104,11 @@ sub init_pattern {
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
sub collect_test_cases ($$$) {
|
||||
sub collect_test_cases ($$$$) {
|
||||
my $opt_reorder= shift; # True if we're reordering tests
|
||||
my $suites= shift; # Semicolon separated list of test suites
|
||||
my $opt_cases= shift;
|
||||
my $opt_skip_test_list= shift;
|
||||
my $cases= []; # Array of hash(one hash for each testcase)
|
||||
|
||||
$do_test_reg= init_pattern($do_test, "--do-test");
|
||||
@ -131,7 +132,7 @@ sub collect_test_cases ($$$) {
|
||||
{
|
||||
foreach my $suite (split(",", $suites))
|
||||
{
|
||||
push(@$cases, collect_one_suite($suite, $opt_cases));
|
||||
push(@$cases, collect_one_suite($suite, $opt_cases, $opt_skip_test_list));
|
||||
last if $some_test_found;
|
||||
}
|
||||
}
|
||||
@ -256,6 +257,7 @@ sub collect_one_suite($)
|
||||
{
|
||||
my $suite= shift; # Test suite name
|
||||
my $opt_cases= shift;
|
||||
my $opt_skip_test_list= shift;
|
||||
my @cases; # Array of hash
|
||||
|
||||
mtr_verbose("Collecting: $suite");
|
||||
@ -317,18 +319,23 @@ sub collect_one_suite($)
|
||||
# Build a hash of disabled testcases for this suite
|
||||
# ----------------------------------------------------------------------
|
||||
my %disabled;
|
||||
if ( open(DISABLED, "$testdir/disabled.def" ) )
|
||||
{
|
||||
while ( <DISABLED> )
|
||||
my @disabled_collection= @{$opt_skip_test_list} if defined @{$opt_skip_test_list};
|
||||
unshift (@disabled_collection, "$testdir/disabled.def");
|
||||
for my $skip (@disabled_collection)
|
||||
{
|
||||
if ( open(DISABLED, $skip ) )
|
||||
{
|
||||
chomp;
|
||||
if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ )
|
||||
while ( <DISABLED> )
|
||||
{
|
||||
$disabled{$1}= $2;
|
||||
chomp;
|
||||
if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ )
|
||||
{
|
||||
$disabled{$1}= $2 if not exists $disabled{$1};
|
||||
}
|
||||
}
|
||||
close DISABLED;
|
||||
}
|
||||
close DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
# Read suite.opt file
|
||||
my $suite_opt_file= "$testdir/suite.opt";
|
||||
|
@ -165,6 +165,7 @@ our @opt_extra_mysqld_opt;
|
||||
my $opt_compress;
|
||||
my $opt_ssl;
|
||||
my $opt_skip_ssl;
|
||||
my @opt_skip_test_list;
|
||||
our $opt_ssl_supported;
|
||||
my $opt_ps_protocol;
|
||||
my $opt_sp_protocol;
|
||||
@ -326,7 +327,7 @@ sub main {
|
||||
}
|
||||
|
||||
mtr_report("Collecting tests...");
|
||||
my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases);
|
||||
my $tests= collect_test_cases($opt_reorder, $opt_suites, \@opt_cases, \@opt_skip_test_list);
|
||||
|
||||
if ( $opt_report_features ) {
|
||||
# Put "report features" as the first test to run
|
||||
@ -948,6 +949,7 @@ sub command_line_setup {
|
||||
|
||||
'help|h' => \$opt_usage,
|
||||
'list-options' => \$opt_list_options,
|
||||
'skip-test-list=s' => \@opt_skip_test_list
|
||||
);
|
||||
|
||||
GetOptions(%options) or usage("Can't read options");
|
||||
@ -5440,6 +5442,9 @@ Options to control what test suites or cases to run
|
||||
enable-disabled Run also tests marked as disabled
|
||||
print-testcases Don't run the tests but print details about all the
|
||||
selected tests, in the order they would be run.
|
||||
skip-test-list=FILE Skip the tests listed in FILE. Each line in the file
|
||||
is an entry and should be formatted as:
|
||||
<TESTNAME> : <COMMENT>
|
||||
|
||||
Options that specify ports
|
||||
|
||||
|
@ -333,7 +333,7 @@ rows_examined sql_text
|
||||
2 INSERT INTO t1 SELECT b+sleep(.01) from t2
|
||||
4 UPDATE t1 SET a=a+sleep(.01) WHERE a>2
|
||||
8 UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC
|
||||
2 UPDATE t2 set b=b+sleep(.01) limit 1
|
||||
1 UPDATE t2 set b=b+sleep(.01) limit 1
|
||||
4 UPDATE t1 SET a=a+sleep(.01) WHERE a in (SELECT b from t2)
|
||||
6 DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2
|
||||
DROP TABLE t1,t2;
|
||||
|
@ -2,7 +2,7 @@ DROP TABLE IF EXISTS t1,t2,t3,t2aA,t1Aa;
|
||||
DROP DATABASE IF EXISTS `TEST_$1`;
|
||||
DROP DATABASE IF EXISTS `test_$1`;
|
||||
DROP DATABASE IF EXISTS mysqltest_LC2;
|
||||
CREATE TABLE T1 (a int);
|
||||
CREATE TABLE T1 (a int) ENGINE=MyISAM;
|
||||
INSERT INTO T1 VALUES (1);
|
||||
SHOW TABLES LIKE "T1";
|
||||
Tables_in_test (T1)
|
||||
|
@ -1191,6 +1191,9 @@ SHOW CREATE TABLE t4;
|
||||
ERROR HY000: Table 't4' was not locked with LOCK TABLES
|
||||
INSERT INTO t4 VALUES (4);
|
||||
ERROR HY000: Table 't4' was not locked with LOCK TABLES
|
||||
# Temporary tables can be created in spite of LOCK TABLES.
|
||||
# If the temporary MERGE table uses the locked children only,
|
||||
# it can even be used.
|
||||
CREATE TEMPORARY TABLE t4 LIKE t3;
|
||||
SHOW CREATE TABLE t4;
|
||||
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
|
||||
@ -1672,6 +1675,7 @@ c1
|
||||
33
|
||||
DELETE FROM t4 WHERE c1 = 33;
|
||||
DROP TRIGGER t3_ai;
|
||||
UNLOCK TABLES;
|
||||
#
|
||||
# Trigger with table use on child
|
||||
DELETE FROM t4 WHERE c1 = 4;
|
||||
@ -1854,9 +1858,9 @@ ALTER TABLE t2 UNION=(t3,t1);
|
||||
SELECT * FROM t2;
|
||||
ERROR HY000: Table 't3' is differently defined or of non-MyISAM type or doesn't exist
|
||||
DROP TABLE t1, t2, t3;
|
||||
CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
|
||||
CREATE TABLE t2 (c1 INT) ENGINE= MyISAM;
|
||||
CREATE TABLE t3 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1, t2);
|
||||
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
|
||||
CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
|
||||
CREATE TABLE t3 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
INSERT INTO t2 VALUES (2);
|
||||
SELECT * FROM t3;
|
||||
@ -2635,6 +2639,17 @@ DROP TRIGGER t2_au;
|
||||
DROP FUNCTION f1;
|
||||
DROP TABLE tm1, t1, t2, t3, t4, t5;
|
||||
#
|
||||
# Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE
|
||||
#
|
||||
CREATE TEMPORARY TABLE t1 (c1 INT);
|
||||
ALTER TABLE t1 ENGINE=MERGE UNION(t_not_exists,t1);
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize Error Table 'test.t_not_exists' doesn't exist
|
||||
test.t1 optimize Error Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
|
||||
test.t1 optimize note The storage engine for the table doesn't support optimize
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# Bug47098 assert in MDL_context::destroy on HANDLER
|
||||
# <damaged merge table> OPEN
|
||||
#
|
||||
@ -2700,6 +2715,18 @@ ALTER TABLE m1 ADD INDEX (c1);
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE m1, t1;
|
||||
#
|
||||
# If children are to be altered, they need an explicit lock.
|
||||
#
|
||||
CREATE TABLE t1 (c1 INT);
|
||||
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1);
|
||||
LOCK TABLE m1 WRITE;
|
||||
ALTER TABLE t1 ADD INDEX (c1);
|
||||
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
|
||||
LOCK TABLE m1 WRITE, t1 WRITE;
|
||||
ALTER TABLE t1 ADD INDEX (c1);
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE m1, t1;
|
||||
#
|
||||
# Test for bug #37371 "CREATE TABLE LIKE merge loses UNION parameter"
|
||||
#
|
||||
drop tables if exists t1, m1, m2;
|
||||
|
1074
mysql-test/r/single_delete_update.result
Normal file
1074
mysql-test/r/single_delete_update.result
Normal file
File diff suppressed because it is too large
Load Diff
@ -59,3 +59,28 @@ FROM t3 WHERE 1 = 0 GROUP BY 1;
|
||||
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
||||
DROP TABLE t1,t2,t3;
|
||||
End of 5.0 tests.
|
||||
#
|
||||
# Bug#53236 Segfault in DTCollation::set(DTCollation&)
|
||||
#
|
||||
CREATE TABLE t1 (
|
||||
pk INTEGER AUTO_INCREMENT,
|
||||
col_varchar VARCHAR(1),
|
||||
PRIMARY KEY (pk)
|
||||
)
|
||||
;
|
||||
INSERT INTO t1 (col_varchar)
|
||||
VALUES
|
||||
('w'),
|
||||
('m')
|
||||
;
|
||||
SELECT table1.pk
|
||||
FROM ( t1 AS table1 JOIN t1 AS table2 ON (table1.col_varchar =
|
||||
table2.col_varchar) )
|
||||
WHERE ( 1, 2 ) IN ( SELECT SUBQUERY1_t1.pk AS SUBQUERY1_field1,
|
||||
SUBQUERY1_t1.pk AS SUBQUERY1_field2
|
||||
FROM ( t1 AS SUBQUERY1_t1 JOIN t1 AS SUBQUERY1_t2
|
||||
ON (SUBQUERY1_t2.col_varchar =
|
||||
SUBQUERY1_t1.col_varchar) ) )
|
||||
;
|
||||
pk
|
||||
drop table t1;
|
||||
|
@ -306,8 +306,8 @@ Handler_read_first 0
|
||||
Handler_read_key 0
|
||||
Handler_read_next 0
|
||||
Handler_read_prev 0
|
||||
Handler_read_rnd 1
|
||||
Handler_read_rnd_next 9
|
||||
Handler_read_rnd 0
|
||||
Handler_read_rnd_next 0
|
||||
alter table t1 disable keys;
|
||||
flush status;
|
||||
delete from t1 order by a limit 1;
|
||||
|
32
mysql-test/suite/rpl/r/rpl_savepoint.result
Normal file
32
mysql-test/suite/rpl/r/rpl_savepoint.result
Normal file
@ -0,0 +1,32 @@
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
#
|
||||
# Bug#50124 Rpl failure on DROP table with concurrent txn/non-txn
|
||||
# DML flow and SAVEPOINT
|
||||
#
|
||||
# Connection master
|
||||
DROP TABLE IF EXISTS tt, nt;
|
||||
CREATE TABLE tt (i INT) ENGINE = InnoDB;
|
||||
CREATE TABLE nt (i INT) ENGINE = MyISAM;
|
||||
FLUSH LOGS;
|
||||
START TRANSACTION;
|
||||
INSERT INTO nt VALUES (1);
|
||||
SAVEPOINT insert_statement;
|
||||
INSERT INTO tt VALUES (1);
|
||||
# Connection master1
|
||||
# Sending:
|
||||
DROP TABLE tt;
|
||||
# Connection master
|
||||
ROLLBACK TO SAVEPOINT insert_statement;
|
||||
Warnings:
|
||||
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
||||
COMMIT;
|
||||
# Connection master1
|
||||
# Reaping: DROP TABLE tt
|
||||
FLUSH LOGS;
|
||||
# Connection master
|
||||
DROP TABLE nt;
|
47
mysql-test/suite/rpl/t/rpl_savepoint.test
Normal file
47
mysql-test/suite/rpl/t/rpl_savepoint.test
Normal file
@ -0,0 +1,47 @@
|
||||
--source include/master-slave.inc
|
||||
--source include/have_innodb.inc
|
||||
|
||||
--echo #
|
||||
--echo # Bug#50124 Rpl failure on DROP table with concurrent txn/non-txn
|
||||
--echo # DML flow and SAVEPOINT
|
||||
--echo #
|
||||
|
||||
--echo # Connection master
|
||||
connection master;
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS tt, nt;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE tt (i INT) ENGINE = InnoDB;
|
||||
CREATE TABLE nt (i INT) ENGINE = MyISAM;
|
||||
FLUSH LOGS;
|
||||
START TRANSACTION;
|
||||
INSERT INTO nt VALUES (1);
|
||||
SAVEPOINT insert_statement;
|
||||
INSERT INTO tt VALUES (1);
|
||||
|
||||
--echo # Connection master1
|
||||
connection master1;
|
||||
--echo # Sending:
|
||||
--send DROP TABLE tt
|
||||
|
||||
--echo # Connection master
|
||||
connection master;
|
||||
let $wait_condition=
|
||||
SELECT COUNT(*) = 1 FROM information_schema.processlist
|
||||
WHERE state = "Waiting for table" AND info = "DROP TABLE tt";
|
||||
--source include/wait_condition.inc
|
||||
ROLLBACK TO SAVEPOINT insert_statement;
|
||||
COMMIT;
|
||||
|
||||
--echo # Connection master1
|
||||
connection master1;
|
||||
--echo # Reaping: DROP TABLE tt
|
||||
--reap
|
||||
FLUSH LOGS;
|
||||
|
||||
--echo # Connection master
|
||||
connection master;
|
||||
DROP TABLE nt;
|
||||
--source include/master-slave-end.inc
|
@ -16,7 +16,7 @@ DROP DATABASE IF EXISTS `test_$1`;
|
||||
DROP DATABASE IF EXISTS mysqltest_LC2;
|
||||
--enable_warnings
|
||||
|
||||
CREATE TABLE T1 (a int);
|
||||
CREATE TABLE T1 (a int) ENGINE=MyISAM;
|
||||
INSERT INTO T1 VALUES (1);
|
||||
SHOW TABLES LIKE "T1";
|
||||
SHOW TABLES LIKE "t1";
|
||||
|
@ -457,7 +457,7 @@ CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1);
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t1, t2;
|
||||
CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3);
|
||||
--error 1168
|
||||
--error ER_WRONG_MRG_TABLE
|
||||
SELECT * FROM t2;
|
||||
DROP TABLE t2;
|
||||
|
||||
@ -549,11 +549,11 @@ drop table t1;
|
||||
# CREATE TABLE fails
|
||||
#
|
||||
CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2);
|
||||
--error 1168
|
||||
--error ER_WRONG_MRG_TABLE
|
||||
SELECT * FROM tm1;
|
||||
CHECK TABLE tm1;
|
||||
CREATE TABLE t1(a INT);
|
||||
--error 1168
|
||||
--error ER_WRONG_MRG_TABLE
|
||||
SELECT * FROM tm1;
|
||||
CHECK TABLE tm1;
|
||||
CREATE TABLE t2(a BLOB);
|
||||
@ -887,6 +887,9 @@ CREATE TABLE t4 LIKE t3;
|
||||
SHOW CREATE TABLE t4;
|
||||
--error ER_TABLE_NOT_LOCKED
|
||||
INSERT INTO t4 VALUES (4);
|
||||
--echo # Temporary tables can be created in spite of LOCK TABLES.
|
||||
--echo # If the temporary MERGE table uses the locked children only,
|
||||
--echo # it can even be used.
|
||||
CREATE TEMPORARY TABLE t4 LIKE t3;
|
||||
--error ER_WRONG_MRG_TABLE
|
||||
SHOW CREATE TABLE t4;
|
||||
@ -913,7 +916,7 @@ DROP TABLE t4;
|
||||
--echo # 2. Normal rename.
|
||||
SELECT * FROM t3 ORDER BY c1;
|
||||
RENAME TABLE t2 TO t5;
|
||||
--error 1168
|
||||
--error ER_WRONG_MRG_TABLE
|
||||
SELECT * FROM t3 ORDER BY c1;
|
||||
RENAME TABLE t5 TO t2;
|
||||
SELECT * FROM t3 ORDER BY c1;
|
||||
@ -931,7 +934,7 @@ UNLOCK TABLES;
|
||||
--echo #
|
||||
--echo # 4. Alter table rename.
|
||||
ALTER TABLE t2 RENAME TO t5;
|
||||
--error 1168
|
||||
--error ER_WRONG_MRG_TABLE
|
||||
SELECT * FROM t3 ORDER BY c1;
|
||||
ALTER TABLE t5 RENAME TO t2;
|
||||
SELECT * FROM t3 ORDER BY c1;
|
||||
@ -1170,6 +1173,7 @@ SELECT @a;
|
||||
SELECT * FROM t4 ORDER BY c1;
|
||||
DELETE FROM t4 WHERE c1 = 33;
|
||||
DROP TRIGGER t3_ai;
|
||||
UNLOCK TABLES;
|
||||
--echo #
|
||||
--echo # Trigger with table use on child
|
||||
DELETE FROM t4 WHERE c1 = 4;
|
||||
@ -1273,11 +1277,12 @@ DROP TABLE t1, t2, t3;
|
||||
|
||||
#
|
||||
# Bug#25038 - Waiting TRUNCATE
|
||||
# Truncate failed with error message when table was in use by MERGE.
|
||||
#
|
||||
# Show that truncate of child table after use of parent table works.
|
||||
CREATE TABLE t1 (c1 INT) ENGINE= MyISAM;
|
||||
CREATE TABLE t2 (c1 INT) ENGINE= MyISAM;
|
||||
CREATE TABLE t3 (c1 INT) ENGINE= MRG_MYISAM UNION= (t1, t2);
|
||||
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
|
||||
CREATE TABLE t2 (c1 INT) ENGINE=MyISAM;
|
||||
CREATE TABLE t3 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,t2);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
INSERT INTO t2 VALUES (2);
|
||||
SELECT * FROM t3;
|
||||
@ -1429,7 +1434,6 @@ FLUSH TABLES m1, t1;
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE t1, m1;
|
||||
|
||||
|
||||
#
|
||||
# Bug#35068 - Assertion fails when reading from i_s.tables
|
||||
# and there is incorrect merge table
|
||||
@ -1816,7 +1820,7 @@ CREATE TABLE m1 (c1 INT) ENGINE=MRG_MYISAM UNION=(t1,mysql_test1.t2)
|
||||
INSERT INTO t1 VALUES (1);
|
||||
INSERT INTO mysql_test1.t2 VALUES (2);
|
||||
SELECT * FROM m1;
|
||||
#--copy_file $MYSQLTEST_VARDIR/master-data/test/m1.MRG /tmp/mysql-test-m1.MRG
|
||||
#--copy_file $MYSQLTEST_DATADIR/test/m1.MRG /tmp/mysql-test-m1.MRG
|
||||
DROP TABLE t1, mysql_test1.t2, m1;
|
||||
DROP DATABASE mysql_test1;
|
||||
#
|
||||
@ -2104,6 +2108,14 @@ DROP TRIGGER t2_au;
|
||||
DROP FUNCTION f1;
|
||||
DROP TABLE tm1, t1, t2, t3, t4, t5;
|
||||
|
||||
--echo #
|
||||
--echo # Bug#47633 - assert in ha_myisammrg::info during OPTIMIZE
|
||||
--echo #
|
||||
CREATE TEMPORARY TABLE t1 (c1 INT);
|
||||
ALTER TABLE t1 ENGINE=MERGE UNION(t_not_exists,t1);
|
||||
OPTIMIZE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # Bug47098 assert in MDL_context::destroy on HANDLER
|
||||
--echo # <damaged merge table> OPEN
|
||||
@ -2186,6 +2198,18 @@ ALTER TABLE m1 ADD INDEX (c1);
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE m1, t1;
|
||||
|
||||
--echo #
|
||||
--echo # If children are to be altered, they need an explicit lock.
|
||||
--echo #
|
||||
CREATE TABLE t1 (c1 INT);
|
||||
CREATE TABLE m1 (c1 INT) ENGINE=MRG_MyISAM UNION=(t1);
|
||||
LOCK TABLE m1 WRITE;
|
||||
--error ER_TABLE_NOT_LOCKED_FOR_WRITE
|
||||
ALTER TABLE t1 ADD INDEX (c1);
|
||||
LOCK TABLE m1 WRITE, t1 WRITE;
|
||||
ALTER TABLE t1 ADD INDEX (c1);
|
||||
UNLOCK TABLES;
|
||||
DROP TABLE m1, t1;
|
||||
|
||||
--echo #
|
||||
--echo # Test for bug #37371 "CREATE TABLE LIKE merge loses UNION parameter"
|
||||
|
481
mysql-test/t/single_delete_update.test
Normal file
481
mysql-test/t/single_delete_update.test
Normal file
@ -0,0 +1,481 @@
|
||||
#
|
||||
# Single table specific update/delete tests (mysql_update and mysql_delete)
|
||||
#
|
||||
|
||||
--echo #
|
||||
--echo # Bug #30584: delete with order by and limit clauses does not use
|
||||
--echo # limit efficiently
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
INSERT INTO t1 VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19),
|
||||
(20),(21),(22),(23),(24),(25);
|
||||
|
||||
CREATE TABLE t2(a INT, i INT PRIMARY KEY);
|
||||
INSERT INTO t2 (i) SELECT i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # index on field prefix:
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2(a INT, i CHAR(2), INDEX(i(1)));
|
||||
INSERT INTO t2 (i) SELECT i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # constant inside ORDER BY list, should use filesort
|
||||
--echo # on a small table
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2(a INT, b INT, c INT, d INT, INDEX(a, b, c));
|
||||
INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
let $cnt = `SELECT COUNT(*) FROM t2 WHERE b = 10`;
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
--echo ## should be 5 (previous LIMIT)
|
||||
eval SELECT $cnt - COUNT(*) FROM t2 WHERE b = 10;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # same test as above (constant inside ORDER BY list), but with
|
||||
--echo # a larger table - should not use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2(a INT, b INT, c INT, d INT, INDEX(a, b, c));
|
||||
INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1;
|
||||
|
||||
INSERT INTO t2 (a, b, c) SELECT t1.i, t1.i, t1.i FROM t1, t1 x1, t1 x2;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
let $cnt = `SELECT COUNT(*) FROM t2 WHERE b = 10`;
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
--echo ## should be 5 (previous LIMIT)
|
||||
eval SELECT $cnt - COUNT(*) FROM t2 WHERE b = 10;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # as above + partial index, should use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (a CHAR(2), b CHAR(2), c CHAR(2), d CHAR(2), INDEX (a,b(1),c));
|
||||
INSERT INTO t2 SELECT i, i, i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # as above but index is without HA_READ_ORDER flag, should use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (a CHAR(2), b CHAR(2), c CHAR(2), d CHAR(2), INDEX (a,b,c)) ENGINE=HEAP;
|
||||
INSERT INTO t2 SELECT i, i, i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # quick select is Index Merge, should use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (i INT, key1 INT, key2 INT, INDEX (key1), INDEX (key2));
|
||||
INSERT INTO t2 (key1, key2) SELECT i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
--replace_column 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
|
||||
EXPLAIN EXTENDED SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
--replace_column 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
|
||||
EXPLAIN EXTENDED SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # reverse quick select, should not use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2(a INT, i INT PRIMARY KEY);
|
||||
INSERT INTO t2 (i) SELECT i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # mixed sorting direction, should use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (a CHAR(2), b CHAR(2), c CHAR(2), INDEX (a, b));
|
||||
INSERT INTO t2 SELECT i, i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 ORDER BY a, b DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 ORDER BY a, b DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 ORDER BY a, b DESC;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # LIMIT with no WHERE and DESC direction, should not use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (a CHAR(2), b CHAR(2), c CHAR(2), INDEX (a, b));
|
||||
INSERT INTO t2 (a, b) SELECT i, i FROM t1;
|
||||
INSERT INTO t2 (a, b) SELECT t1.i, t1.i FROM t1, t1 x1, t1 x2;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 ORDER BY a, b LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 ORDER BY a DESC, b DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
DELETE FROM t2 ORDER BY a DESC, b DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE c = 10 ORDER BY a DESC, b DESC;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug #36569: UPDATE ... WHERE ... ORDER BY... always does a filesort
|
||||
--echo # even if not required
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (i INT);
|
||||
INSERT INTO t1 VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19),
|
||||
(20),(21),(22),(23),(24),(25);
|
||||
|
||||
CREATE TABLE t2(a INT, i INT PRIMARY KEY);
|
||||
INSERT INTO t2 (i) SELECT i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # index on field prefix:
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2(a INT, i CHAR(2), INDEX(i(1)));
|
||||
INSERT INTO t2 (i) SELECT i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # constant inside ORDER BY list, should use filesort
|
||||
--echo # on a small table
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2(a INT, b INT, c INT, d INT, INDEX(a, b, c));
|
||||
INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
let $cnt = `SELECT COUNT(*) FROM t2 WHERE b = 10`;
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
--echo ## should be 5 (previous LIMIT)
|
||||
SELECT COUNT(*) FROM t2 WHERE b = 10 AND d = 10 ORDER BY a, c;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # same test as above (constant inside ORDER BY list), but with
|
||||
--echo # a larger table - should not use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2(a INT, b INT, c INT, d INT, INDEX(a, b, c));
|
||||
INSERT INTO t2 (a, b, c) SELECT i, i, i FROM t1;
|
||||
|
||||
INSERT INTO t2 (a, b, c) SELECT t1.i, t1.i, t1.i FROM t1, t1 x1, t1 x2;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
let $cnt = `SELECT COUNT(*) FROM t2 WHERE b = 10`;
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
--echo ## should be 5 (previous LIMIT)
|
||||
SELECT COUNT(*) FROM t2 WHERE b = 10 AND d = 10 ORDER BY a, c;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # as above + partial index, should use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (a CHAR(2), b CHAR(2), c CHAR(2), d CHAR(2), INDEX (a,b(1),c));
|
||||
INSERT INTO t2 SELECT i, i, i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # as above but index is without HA_READ_ORDER flag, should use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (a CHAR(2), b CHAR(2), c CHAR(2), d CHAR(2), INDEX (a,b,c)) ENGINE=HEAP;
|
||||
INSERT INTO t2 SELECT i, i, i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET d = 10 WHERE b = 10 ORDER BY a, c LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE b = 10 ORDER BY a, c;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # quick select is Index Merge, should use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (i INT, key1 INT, key2 INT, INDEX (key1), INDEX (key2));
|
||||
INSERT INTO t2 (key1, key2) SELECT i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
--replace_column 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
|
||||
EXPLAIN EXTENDED SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET i = 123 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
--replace_column 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x
|
||||
EXPLAIN EXTENDED SELECT * FROM t2 WHERE key1 < 13 or key2 < 14 ORDER BY key1;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # reverse quick select, should not use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2(a INT, i INT PRIMARY KEY);
|
||||
INSERT INTO t2 (i) SELECT i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET a = 10 WHERE i > 10 AND i <= 18 ORDER BY i DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE i > 10 AND i <= 18 ORDER BY i;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # mixed sorting direction, should use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (a CHAR(2), b CHAR(2), c CHAR(2), INDEX (a, b));
|
||||
INSERT INTO t2 SELECT i, i, i FROM t1;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 ORDER BY a, b DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET c = 10 ORDER BY a, b DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE c = 10 ORDER BY a, b DESC;
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
--echo #
|
||||
--echo # LIMIT with no WHERE and DESC direction, should not use filesort
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t2 (a CHAR(2), b CHAR(2), c CHAR(2), INDEX (a, b));
|
||||
INSERT INTO t2 (a, b) SELECT i, i FROM t1;
|
||||
INSERT INTO t2 (a, b) SELECT t1.i, t1.i FROM t1, t1 x1, t1 x2;
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 ORDER BY a, b LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
SELECT * FROM t2 ORDER BY a DESC, b DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
|
||||
FLUSH STATUS;
|
||||
UPDATE t2 SET c = 10 ORDER BY a DESC, b DESC LIMIT 5;
|
||||
SHOW SESSION STATUS LIKE 'Sort%';
|
||||
SHOW STATUS LIKE 'Handler_read_%';
|
||||
SELECT * FROM t2 WHERE c = 10 ORDER BY a DESC, b DESC;
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # Bug #53742: UPDATEs have no effect after applying patch for bug 36569
|
||||
--echo #
|
||||
|
||||
--disable_warnings
|
||||
CREATE TABLE t1 (
|
||||
pk INT NOT NULL AUTO_INCREMENT,
|
||||
c1_idx CHAR(1) DEFAULT 'y',
|
||||
c2 INT,
|
||||
PRIMARY KEY (pk),
|
||||
INDEX c1_idx (c1_idx)
|
||||
) ENGINE=InnoDB;
|
||||
--enable_warnings
|
||||
|
||||
INSERT INTO t1 VALUES (), (), (), ();
|
||||
|
||||
SELECT * FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2;
|
||||
UPDATE t1 SET c2 = 0 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2;
|
||||
SELECT * FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2;
|
||||
SELECT * FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC;
|
||||
|
||||
DELETE FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC LIMIT 2;
|
||||
SELECT * FROM t1 WHERE c1_idx = 'y' ORDER BY pk DESC;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
@ -62,3 +62,32 @@ FROM t3 WHERE 1 = 0 GROUP BY 1;
|
||||
DROP TABLE t1,t2,t3;
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
||||
--echo #
|
||||
--echo # Bug#53236 Segfault in DTCollation::set(DTCollation&)
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (
|
||||
pk INTEGER AUTO_INCREMENT,
|
||||
col_varchar VARCHAR(1),
|
||||
PRIMARY KEY (pk)
|
||||
)
|
||||
;
|
||||
|
||||
INSERT INTO t1 (col_varchar)
|
||||
VALUES
|
||||
('w'),
|
||||
('m')
|
||||
;
|
||||
|
||||
SELECT table1.pk
|
||||
FROM ( t1 AS table1 JOIN t1 AS table2 ON (table1.col_varchar =
|
||||
table2.col_varchar) )
|
||||
WHERE ( 1, 2 ) IN ( SELECT SUBQUERY1_t1.pk AS SUBQUERY1_field1,
|
||||
SUBQUERY1_t1.pk AS SUBQUERY1_field2
|
||||
FROM ( t1 AS SUBQUERY1_t1 JOIN t1 AS SUBQUERY1_t2
|
||||
ON (SUBQUERY1_t2.col_varchar =
|
||||
SUBQUERY1_t1.col_varchar) ) )
|
||||
;
|
||||
|
||||
drop table t1;
|
||||
|
@ -93,23 +93,33 @@ int nt_share_delete(const char *name, myf MyFlags)
|
||||
name, buf, errno));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (errno == ERROR_FILE_NOT_FOUND)
|
||||
{
|
||||
my_errno= ENOENT; // marking, that `name' doesn't exist
|
||||
my_errno= ENOENT; // marking, that `name' doesn't exist
|
||||
}
|
||||
else if (errno == 0)
|
||||
{
|
||||
if (DeleteFile(buf))
|
||||
DBUG_RETURN(0);
|
||||
else if ((my_errno= GetLastError()) == 0)
|
||||
my_errno= ENOENT; // marking, that `buf' doesn't exist
|
||||
} else
|
||||
my_errno= errno;
|
||||
|
||||
if (DeleteFile(buf))
|
||||
DBUG_RETURN(0);
|
||||
/*
|
||||
The below is more complicated than necessary. For some reason, the
|
||||
assignment to my_errno clears the error number, which is retrieved
|
||||
by GetLastError() (VC2005EE). Assigning to errno first, allows to
|
||||
retrieve the correct value.
|
||||
*/
|
||||
errno= GetLastError();
|
||||
if (errno == 0)
|
||||
my_errno= ENOENT; // marking, that `buf' doesn't exist
|
||||
else
|
||||
my_errno= errno;
|
||||
}
|
||||
else
|
||||
my_errno= errno;
|
||||
|
||||
if (MyFlags & (MY_FAE+MY_WME))
|
||||
my_error(EE_DELETE, MYF(ME_BELL + ME_WAITTANG + (MyFlags & ME_NOINPUT)),
|
||||
name, my_errno);
|
||||
my_error(EE_DELETE, MYF(ME_BELL + ME_WAITTANG + (MyFlags & ME_NOINPUT)),
|
||||
name, my_errno);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
#endif
|
||||
|
@ -38,13 +38,16 @@ void *my_mmap(void *addr, size_t len, int prot,
|
||||
HANDLE hFileMap;
|
||||
LPVOID ptr;
|
||||
HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
|
||||
DBUG_ENTER("my_mmap");
|
||||
DBUG_PRINT("mysys", ("map fd: %d", fd));
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return MAP_FAILED;
|
||||
DBUG_RETURN(MAP_FAILED);
|
||||
|
||||
hFileMap=CreateFileMapping(hFile, &mmap_security_attributes,
|
||||
PAGE_READWRITE, 0, (DWORD) len, NULL);
|
||||
if (hFileMap == 0)
|
||||
return MAP_FAILED;
|
||||
DBUG_RETURN(MAP_FAILED);
|
||||
|
||||
ptr=MapViewOfFile(hFileMap,
|
||||
prot & PROT_WRITE ? FILE_MAP_WRITE : FILE_MAP_READ,
|
||||
@ -59,14 +62,19 @@ void *my_mmap(void *addr, size_t len, int prot,
|
||||
CloseHandle(hFileMap);
|
||||
|
||||
if (ptr)
|
||||
return ptr;
|
||||
{
|
||||
DBUG_PRINT("mysys", ("mapped addr: %p", ptr));
|
||||
DBUG_RETURN(ptr);
|
||||
}
|
||||
|
||||
return MAP_FAILED;
|
||||
DBUG_RETURN(MAP_FAILED);
|
||||
}
|
||||
|
||||
int my_munmap(void *addr, size_t len)
|
||||
{
|
||||
return UnmapViewOfFile(addr) ? 0 : -1;
|
||||
DBUG_ENTER("my_munmap");
|
||||
DBUG_PRINT("mysys", ("unmap addr: %p", addr));
|
||||
DBUG_RETURN(UnmapViewOfFile(addr) ? 0 : -1);
|
||||
}
|
||||
|
||||
int my_msync(int fd, void *addr, size_t len, int flags)
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "sp_rcontext.h"
|
||||
#include "sp.h"
|
||||
#include "set_var.h"
|
||||
#include "debug_sync.h"
|
||||
|
||||
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
||||
#define sp_restore_security_context(A,B) while (0) {}
|
||||
@ -1941,6 +1942,8 @@ double Item_func_pow::val_real()
|
||||
double Item_func_acos::val_real()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
/* One can use this to defer SELECT processing. */
|
||||
DEBUG_SYNC(current_thd, "before_acos_function");
|
||||
// the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug)
|
||||
volatile double value= args[0]->val_real();
|
||||
if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
|
||||
|
115
sql/opt_range.cc
115
sql/opt_range.cc
@ -1841,96 +1841,6 @@ SEL_ARG *SEL_ARG::clone_tree(RANGE_OPT_PARAM *param)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Find the best index to retrieve first N records in given order
|
||||
|
||||
SYNOPSIS
|
||||
get_index_for_order()
|
||||
table Table to be accessed
|
||||
order Required ordering
|
||||
limit Number of records that will be retrieved
|
||||
|
||||
DESCRIPTION
|
||||
Find the best index that allows to retrieve first #limit records in the
|
||||
given order cheaper then one would retrieve them using full table scan.
|
||||
|
||||
IMPLEMENTATION
|
||||
Run through all table indexes and find the shortest index that allows
|
||||
records to be retrieved in given order. We look for the shortest index
|
||||
as we will have fewer index pages to read with it.
|
||||
|
||||
This function is used only by UPDATE/DELETE, so we take into account how
|
||||
the UPDATE/DELETE code will work:
|
||||
* index can only be scanned in forward direction
|
||||
* HA_EXTRA_KEYREAD will not be used
|
||||
Perhaps these assumptions could be relaxed.
|
||||
|
||||
RETURN
|
||||
Number of the index that produces the required ordering in the cheapest way
|
||||
MAX_KEY if no such index was found.
|
||||
*/
|
||||
|
||||
uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit)
|
||||
{
|
||||
uint idx;
|
||||
uint match_key= MAX_KEY, match_key_len= MAX_KEY_LENGTH + 1;
|
||||
ORDER *ord;
|
||||
|
||||
for (ord= order; ord; ord= ord->next)
|
||||
if (!ord->asc)
|
||||
return MAX_KEY;
|
||||
|
||||
for (idx= 0; idx < table->s->keys; idx++)
|
||||
{
|
||||
if (!(table->keys_in_use_for_query.is_set(idx)))
|
||||
continue;
|
||||
KEY_PART_INFO *keyinfo= table->key_info[idx].key_part;
|
||||
uint n_parts= table->key_info[idx].key_parts;
|
||||
uint partno= 0;
|
||||
|
||||
/*
|
||||
The below check is sufficient considering we now have either BTREE
|
||||
indexes (records are returned in order for any index prefix) or HASH
|
||||
indexes (records are not returned in order for any index prefix).
|
||||
*/
|
||||
if (!(table->file->index_flags(idx, 0, 1) & HA_READ_ORDER))
|
||||
continue;
|
||||
for (ord= order; ord && partno < n_parts; ord= ord->next, partno++)
|
||||
{
|
||||
Item *item= order->item[0];
|
||||
if (!(item->type() == Item::FIELD_ITEM &&
|
||||
((Item_field*)item)->field->eq(keyinfo[partno].field)))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ord && table->key_info[idx].key_length < match_key_len)
|
||||
{
|
||||
/*
|
||||
Ok, the ordering is compatible and this key is shorter then
|
||||
previous match (we want shorter keys as we'll have to read fewer
|
||||
index pages for the same number of records)
|
||||
*/
|
||||
match_key= idx;
|
||||
match_key_len= table->key_info[idx].key_length;
|
||||
}
|
||||
}
|
||||
|
||||
if (match_key != MAX_KEY)
|
||||
{
|
||||
/*
|
||||
Found an index that allows records to be retrieved in the requested
|
||||
order. Now we'll check if using the index is cheaper then doing a table
|
||||
scan.
|
||||
*/
|
||||
double full_scan_time= table->file->scan_time();
|
||||
double index_scan_time= table->file->read_time(match_key, 1, limit);
|
||||
if (index_scan_time > full_scan_time)
|
||||
match_key= MAX_KEY;
|
||||
}
|
||||
return match_key;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Table rows retrieval plan. Range optimizer creates QUICK_SELECT_I-derived
|
||||
objects from table read plans.
|
||||
@ -8977,7 +8887,6 @@ QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
|
||||
}
|
||||
rev_it.rewind();
|
||||
q->dont_free=1; // Don't free shared mem
|
||||
delete q;
|
||||
}
|
||||
|
||||
|
||||
@ -9067,6 +8976,27 @@ int QUICK_SELECT_DESC::get_next()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Create a compatible quick select with the result ordered in an opposite way
|
||||
|
||||
@param used_key_parts_arg Number of used key parts
|
||||
|
||||
@retval NULL in case of errors (OOM etc)
|
||||
@retval pointer to a newly created QUICK_SELECT_DESC if success
|
||||
*/
|
||||
|
||||
QUICK_SELECT_I *QUICK_RANGE_SELECT::make_reverse(uint used_key_parts_arg)
|
||||
{
|
||||
QUICK_SELECT_DESC *new_quick= new QUICK_SELECT_DESC(this, used_key_parts_arg);
|
||||
if (new_quick == NULL || new_quick->error != 0)
|
||||
{
|
||||
delete new_quick;
|
||||
return NULL;
|
||||
}
|
||||
return new_quick;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Compare if found key is over max-value
|
||||
Returns 0 if key <= range->max_key
|
||||
@ -11673,6 +11603,7 @@ void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
|
||||
/* purecov: end */
|
||||
}
|
||||
|
||||
|
||||
void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
|
||||
{
|
||||
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
|
||||
@ -11761,7 +11692,7 @@ void QUICK_GROUP_MIN_MAX_SELECT::dbug_dump(int indent, bool verbose)
|
||||
}
|
||||
|
||||
|
||||
#endif /* NOT_USED */
|
||||
#endif /* !DBUG_OFF */
|
||||
|
||||
/*****************************************************************************
|
||||
** Instantiate templates
|
||||
|
@ -352,6 +352,11 @@ public:
|
||||
*/
|
||||
virtual void dbug_dump(int indent, bool verbose)= 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Returns a QUICK_SELECT with reverse order of to the index.
|
||||
*/
|
||||
virtual QUICK_SELECT_I *make_reverse(uint used_key_parts_arg) { return NULL; }
|
||||
};
|
||||
|
||||
|
||||
@ -437,6 +442,7 @@ public:
|
||||
#ifndef DBUG_OFF
|
||||
void dbug_dump(int indent, bool verbose);
|
||||
#endif
|
||||
QUICK_SELECT_I *make_reverse(uint used_key_parts_arg);
|
||||
private:
|
||||
/* Default copy ctor used by QUICK_SELECT_DESC */
|
||||
};
|
||||
@ -782,6 +788,10 @@ public:
|
||||
int get_next();
|
||||
bool reverse_sorted() { return 1; }
|
||||
int get_type() { return QS_TYPE_RANGE_DESC; }
|
||||
QUICK_SELECT_I *make_reverse(uint used_key_parts_arg)
|
||||
{
|
||||
return this; // is already reverse sorted
|
||||
}
|
||||
private:
|
||||
bool range_reads_after_key(QUICK_RANGE *range);
|
||||
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
|
||||
@ -807,6 +817,7 @@ class SQL_SELECT :public Sql_alloc {
|
||||
SQL_SELECT();
|
||||
~SQL_SELECT();
|
||||
void cleanup();
|
||||
void set_quick(QUICK_SELECT_I *new_quick) { delete quick; quick= new_quick; }
|
||||
bool check_quick(THD *thd, bool force_quick_range, ha_rows limit)
|
||||
{
|
||||
key_map tmp;
|
||||
@ -833,7 +844,6 @@ public:
|
||||
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
|
||||
struct st_table_ref *ref,
|
||||
ha_rows records);
|
||||
uint get_index_for_order(TABLE *table, ORDER *order, ha_rows limit);
|
||||
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
||||
table_map read_tables, COND *conds,
|
||||
bool allow_null_cond, int *error);
|
||||
|
@ -42,12 +42,14 @@ static int rr_from_cache(READ_RECORD *info);
|
||||
static int init_rr_cache(THD *thd, READ_RECORD *info);
|
||||
static int rr_cmp(uchar *a,uchar *b);
|
||||
static int rr_index_first(READ_RECORD *info);
|
||||
static int rr_index_last(READ_RECORD *info);
|
||||
static int rr_index(READ_RECORD *info);
|
||||
static int rr_index_desc(READ_RECORD *info);
|
||||
|
||||
|
||||
/**
|
||||
Initialize READ_RECORD structure to perform full index scan (in forward
|
||||
direction) using read_record.read_record() interface.
|
||||
Initialize READ_RECORD structure to perform full index scan in desired
|
||||
direction using read_record.read_record() interface
|
||||
|
||||
This function has been added at late stage and is used only by
|
||||
UPDATE/DELETE. Other statements perform index scans using
|
||||
@ -59,10 +61,11 @@ static int rr_index(READ_RECORD *info);
|
||||
@param print_error If true, call table->file->print_error() if an error
|
||||
occurs (except for end-of-records error)
|
||||
@param idx index to scan
|
||||
@param reverse Scan in the reverse direction
|
||||
*/
|
||||
|
||||
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
|
||||
bool print_error, uint idx)
|
||||
bool print_error, uint idx, bool reverse)
|
||||
{
|
||||
empty_record(table);
|
||||
bzero((char*) info,sizeof(*info));
|
||||
@ -77,7 +80,7 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
|
||||
if (!table->file->inited)
|
||||
table->file->ha_index_init(idx, 1);
|
||||
/* read_record will be changed to rr_index in rr_index_first */
|
||||
info->read_record= rr_index_first;
|
||||
info->read_record= reverse ? rr_index_last : rr_index_first;
|
||||
}
|
||||
|
||||
|
||||
@ -364,6 +367,29 @@ static int rr_index_first(READ_RECORD *info)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Reads last row in an index scan.
|
||||
|
||||
@param info Scan info
|
||||
|
||||
@retval
|
||||
0 Ok
|
||||
@retval
|
||||
-1 End of records
|
||||
@retval
|
||||
1 Error
|
||||
*/
|
||||
|
||||
static int rr_index_last(READ_RECORD *info)
|
||||
{
|
||||
int tmp= info->file->index_last(info->record);
|
||||
info->read_record= rr_index_desc;
|
||||
if (tmp)
|
||||
tmp= rr_handle_error(info, tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Reads index sequentially after first row.
|
||||
|
||||
@ -389,6 +415,31 @@ static int rr_index(READ_RECORD *info)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Reads index sequentially from the last row to the first.
|
||||
|
||||
Read the prev index record (in backward direction) and translate return
|
||||
value.
|
||||
|
||||
@param info Scan info
|
||||
|
||||
@retval
|
||||
0 Ok
|
||||
@retval
|
||||
-1 End of records
|
||||
@retval
|
||||
1 Error
|
||||
*/
|
||||
|
||||
static int rr_index_desc(READ_RECORD *info)
|
||||
{
|
||||
int tmp= info->file->index_prev(info->record);
|
||||
if (tmp)
|
||||
tmp= rr_handle_error(info, tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
int rr_sequential(READ_RECORD *info)
|
||||
{
|
||||
int tmp;
|
||||
|
@ -71,7 +71,7 @@ void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form,
|
||||
SQL_SELECT *select, int use_record_cache,
|
||||
bool print_errors, bool disable_rr_cache);
|
||||
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
|
||||
bool print_error, uint idx);
|
||||
bool print_error, uint idx, bool reverse);
|
||||
void end_read_record(READ_RECORD *info);
|
||||
|
||||
void rr_unlock_row(st_join_table *tab);
|
||||
|
@ -47,7 +47,7 @@
|
||||
*/
|
||||
|
||||
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
SQL_I_List<ORDER> *order, ha_rows limit, ulonglong options)
|
||||
SQL_I_List<ORDER> *order_list, ha_rows limit, ulonglong options)
|
||||
{
|
||||
bool will_batch;
|
||||
int error, loc_error;
|
||||
@ -58,6 +58,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
bool transactional_table, safe_update, const_cond;
|
||||
bool const_cond_result;
|
||||
ha_rows deleted= 0;
|
||||
bool reverse= FALSE;
|
||||
ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
|
||||
order_list->first : NULL);
|
||||
uint usable_index= MAX_KEY;
|
||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||
THD::killed_state killed_status= THD::NOT_KILLED;
|
||||
@ -79,7 +82,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
/* check ORDER BY even if it can be ignored */
|
||||
if (order && order->elements)
|
||||
if (order)
|
||||
{
|
||||
TABLE_LIST tables;
|
||||
List<Item> fields;
|
||||
@ -89,9 +92,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
tables.table = table;
|
||||
tables.alias = table_list->alias;
|
||||
|
||||
if (select_lex->setup_ref_array(thd, order->elements) ||
|
||||
if (select_lex->setup_ref_array(thd, order_list->elements) ||
|
||||
setup_order(thd, select_lex->ref_pointer_array, &tables,
|
||||
fields, all_fields, order->first))
|
||||
fields, all_fields, order))
|
||||
{
|
||||
delete select;
|
||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
||||
@ -182,6 +185,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
|
||||
table->covering_keys.clear_all();
|
||||
table->quick_keys.clear_all(); // Can't use 'only index'
|
||||
|
||||
select=make_select(table, 0, 0, conds, 0, &error);
|
||||
if (error)
|
||||
DBUG_RETURN(TRUE);
|
||||
@ -217,22 +221,25 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
if (options & OPTION_QUICK)
|
||||
(void) table->file->extra(HA_EXTRA_QUICK);
|
||||
|
||||
if (order && order->elements)
|
||||
if (order)
|
||||
{
|
||||
uint length= 0;
|
||||
SORT_FIELD *sortorder;
|
||||
ha_rows examined_rows;
|
||||
|
||||
if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
|
||||
usable_index= get_index_for_order(table, order->first, limit);
|
||||
table->update_const_key_parts(conds);
|
||||
order= simple_remove_const(order, conds);
|
||||
|
||||
if (usable_index == MAX_KEY)
|
||||
bool need_sort;
|
||||
usable_index= get_index_for_order(order, table, select, limit,
|
||||
&need_sort, &reverse);
|
||||
if (need_sort)
|
||||
{
|
||||
DBUG_ASSERT(usable_index == MAX_KEY);
|
||||
table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
|
||||
MYF(MY_FAE | MY_ZEROFILL));
|
||||
|
||||
if (!(sortorder= make_unireg_sortorder(order->first,
|
||||
&length, NULL)) ||
|
||||
if (!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
|
||||
(table->sort.found_records = filesort(thd, table, sortorder, length,
|
||||
select, HA_POS_ERROR, 1,
|
||||
&examined_rows))
|
||||
@ -263,7 +270,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
if (usable_index==MAX_KEY || (select && select->quick))
|
||||
init_read_record(&info, thd, table, select, 1, 1, FALSE);
|
||||
else
|
||||
init_read_record_idx(&info, thd, table, 1, usable_index);
|
||||
init_read_record_idx(&info, thd, table, 1, usable_index, reverse);
|
||||
|
||||
init_ftfuncs(thd, select_lex, 1);
|
||||
thd_proc_info(thd, "updating");
|
||||
|
@ -998,7 +998,7 @@ extern const LEX_STRING null_lex_str;
|
||||
extern const LEX_STRING empty_lex_str;
|
||||
|
||||
|
||||
struct Sroutine_hash_entry;
|
||||
class Sroutine_hash_entry;
|
||||
|
||||
/*
|
||||
Class representing list of all tables used by statement and other
|
||||
|
@ -137,7 +137,6 @@ static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
|
||||
static COND *optimize_cond(JOIN *join, COND *conds,
|
||||
List<TABLE_LIST> *join_list,
|
||||
Item::cond_result *cond_value);
|
||||
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
|
||||
static bool open_tmp_table(TABLE *table);
|
||||
static bool create_myisam_tmp_table(TABLE *,TMP_TABLE_PARAM *, ulonglong, my_bool);
|
||||
static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
|
||||
@ -190,6 +189,13 @@ static COND *make_cond_for_table(COND *cond,table_map table,
|
||||
table_map used_table);
|
||||
static Item* part_of_refkey(TABLE *form,Field *field);
|
||||
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
|
||||
static bool test_if_cheaper_ordering(const JOIN_TAB *tab,
|
||||
ORDER *order, TABLE *table,
|
||||
key_map usable_keys, int key,
|
||||
ha_rows select_limit,
|
||||
int *new_key, int *new_key_direction,
|
||||
ha_rows *new_select_limit,
|
||||
uint *new_used_key_parts= NULL);
|
||||
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
|
||||
ha_rows select_limit, bool no_changes,
|
||||
key_map *map);
|
||||
@ -7361,8 +7367,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
|
||||
*simple_order=0;
|
||||
else
|
||||
{
|
||||
Item *comp_item=0;
|
||||
if (cond && const_expression_in_where(cond,order->item[0], &comp_item))
|
||||
if (cond && const_expression_in_where(cond,order->item[0]))
|
||||
{
|
||||
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
|
||||
continue;
|
||||
@ -7392,6 +7397,46 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Filter out ORDER items those are equal to constants in WHERE
|
||||
|
||||
This function is a limited version of remove_const() for use
|
||||
with non-JOIN statements (i.e. single-table UPDATE and DELETE).
|
||||
|
||||
|
||||
@param order Linked list of ORDER BY arguments
|
||||
@param cond WHERE expression
|
||||
|
||||
@return pointer to new filtered ORDER list or NULL if whole list eliminated
|
||||
|
||||
@note
|
||||
This function overwrites input order list.
|
||||
*/
|
||||
|
||||
ORDER *simple_remove_const(ORDER *order, COND *where)
|
||||
{
|
||||
if (!order || !where)
|
||||
return order;
|
||||
|
||||
ORDER *first= NULL, *prev= NULL;
|
||||
for (; order; order= order->next)
|
||||
{
|
||||
DBUG_ASSERT(!order->item[0]->with_sum_func); // should never happen
|
||||
if (!const_expression_in_where(where, order->item[0]))
|
||||
{
|
||||
if (!first)
|
||||
first= order;
|
||||
if (prev)
|
||||
prev->next= order;
|
||||
prev= order;
|
||||
}
|
||||
}
|
||||
if (prev)
|
||||
prev->next= NULL;
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
|
||||
List<Item> &fields, bool send_row, ulonglong select_options,
|
||||
@ -8584,10 +8629,9 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
|
||||
left_item->collation.collation == value->collation.collation))
|
||||
{
|
||||
Item *tmp=value->clone_item();
|
||||
tmp->collation.set(right_item->collation);
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
tmp->collation.set(right_item->collation);
|
||||
thd->change_item_tree(args + 1, tmp);
|
||||
func->update_used_tables();
|
||||
if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
|
||||
@ -8608,10 +8652,9 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
|
||||
right_item->collation.collation == value->collation.collation))
|
||||
{
|
||||
Item *tmp= value->clone_item();
|
||||
tmp->collation.set(left_item->collation);
|
||||
|
||||
if (tmp)
|
||||
{
|
||||
tmp->collation.set(left_item->collation);
|
||||
thd->change_item_tree(args, tmp);
|
||||
value= tmp;
|
||||
func->update_used_tables();
|
||||
@ -9593,13 +9636,50 @@ test_if_equality_guarantees_uniqueness(Item *l, Item *r)
|
||||
l->collation.collation == r->collation.collation)));
|
||||
}
|
||||
|
||||
/**
|
||||
Return TRUE if the item is a const value in all the WHERE clause.
|
||||
|
||||
/*
|
||||
Return TRUE if i1 and i2 (if any) are equal items,
|
||||
or if i1 is a wrapper item around the f2 field.
|
||||
*/
|
||||
|
||||
static bool
|
||||
const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
|
||||
static bool equal(Item *i1, Item *i2, Field *f2)
|
||||
{
|
||||
DBUG_ASSERT((i2 == NULL) ^ (f2 == NULL));
|
||||
|
||||
if (i2 != NULL)
|
||||
return i1->eq(i2, 1);
|
||||
else if (i1->type() == Item::FIELD_ITEM)
|
||||
return f2->eq(((Item_field *) i1)->field);
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Test if a field or an item is equal to a constant value in WHERE
|
||||
|
||||
@param cond WHERE clause expression
|
||||
@param comp_item Item to find in WHERE expression
|
||||
(if comp_field != NULL)
|
||||
@param comp_field Field to find in WHERE expression
|
||||
(if comp_item != NULL)
|
||||
@param[out] const_item intermediate arg, set to Item pointer to NULL
|
||||
|
||||
@return TRUE if the field is a constant value in WHERE
|
||||
|
||||
@note
|
||||
comp_item and comp_field parameters are mutually exclusive.
|
||||
*/
|
||||
bool
|
||||
const_expression_in_where(COND *cond, Item *comp_item, Field *comp_field,
|
||||
Item **const_item)
|
||||
{
|
||||
DBUG_ASSERT((comp_item == NULL) ^ (comp_field == NULL));
|
||||
|
||||
Item *intermediate= NULL;
|
||||
if (const_item == NULL)
|
||||
const_item= &intermediate;
|
||||
|
||||
if (cond->type() == Item::COND_ITEM)
|
||||
{
|
||||
bool and_level= (((Item_cond*) cond)->functype()
|
||||
@ -9608,7 +9688,8 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
|
||||
Item *item;
|
||||
while ((item=li++))
|
||||
{
|
||||
bool res=const_expression_in_where(item, comp_item, const_item);
|
||||
bool res=const_expression_in_where(item, comp_item, comp_field,
|
||||
const_item);
|
||||
if (res) // Is a const value
|
||||
{
|
||||
if (and_level)
|
||||
@ -9620,14 +9701,14 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
|
||||
return and_level ? 0 : 1;
|
||||
}
|
||||
else if (cond->eq_cmp_result() != Item::COND_OK)
|
||||
{ // boolan compare function
|
||||
{ // boolean compare function
|
||||
Item_func* func= (Item_func*) cond;
|
||||
if (func->functype() != Item_func::EQUAL_FUNC &&
|
||||
func->functype() != Item_func::EQ_FUNC)
|
||||
return 0;
|
||||
Item *left_item= ((Item_func*) cond)->arguments()[0];
|
||||
Item *right_item= ((Item_func*) cond)->arguments()[1];
|
||||
if (left_item->eq(comp_item,1))
|
||||
if (equal(left_item, comp_item, comp_field))
|
||||
{
|
||||
if (test_if_equality_guarantees_uniqueness (left_item, right_item))
|
||||
{
|
||||
@ -9637,7 +9718,7 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else if (right_item->eq(comp_item,1))
|
||||
else if (equal(right_item, comp_item, comp_field))
|
||||
{
|
||||
if (test_if_equality_guarantees_uniqueness (right_item, left_item))
|
||||
{
|
||||
@ -9651,6 +9732,7 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Create internal temporary table
|
||||
****************************************************************************/
|
||||
@ -13104,7 +13186,8 @@ part_of_refkey(TABLE *table,Field *field)
|
||||
@param order Sort order
|
||||
@param table Table to sort
|
||||
@param idx Index to check
|
||||
@param used_key_parts Return value for used key parts.
|
||||
@param used_key_parts [out] NULL by default, otherwise return value for
|
||||
used key parts.
|
||||
|
||||
|
||||
@note
|
||||
@ -13123,13 +13206,14 @@ part_of_refkey(TABLE *table,Field *field)
|
||||
*/
|
||||
|
||||
static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||
uint *used_key_parts)
|
||||
uint *used_key_parts= NULL)
|
||||
{
|
||||
KEY_PART_INFO *key_part,*key_part_end;
|
||||
key_part=table->key_info[idx].key_part;
|
||||
key_part_end=key_part+table->key_info[idx].key_parts;
|
||||
key_part_map const_key_parts=table->const_key_parts[idx];
|
||||
int reverse=0;
|
||||
uint key_parts;
|
||||
my_bool on_pk_suffix= FALSE;
|
||||
DBUG_ENTER("test_if_order_by_key");
|
||||
|
||||
@ -13170,8 +13254,9 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||
*/
|
||||
if (key_part == key_part_end && reverse == 0)
|
||||
{
|
||||
*used_key_parts= 0;
|
||||
DBUG_RETURN(1);
|
||||
key_parts= 0;
|
||||
reverse= 1;
|
||||
goto ok;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -13194,7 +13279,7 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||
uint used_key_parts_secondary= table->key_info[idx].key_parts;
|
||||
uint used_key_parts_pk=
|
||||
(uint) (key_part - table->key_info[table->s->primary_key].key_part);
|
||||
*used_key_parts= used_key_parts_pk + used_key_parts_secondary;
|
||||
key_parts= used_key_parts_pk + used_key_parts_secondary;
|
||||
|
||||
if (reverse == -1 &&
|
||||
(!(table->file->index_flags(idx, used_key_parts_secondary - 1, 1) &
|
||||
@ -13205,11 +13290,14 @@ static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
|
||||
}
|
||||
else
|
||||
{
|
||||
*used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
|
||||
key_parts= (uint) (key_part - table->key_info[idx].key_part);
|
||||
if (reverse == -1 &&
|
||||
!(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV))
|
||||
!(table->file->index_flags(idx, key_parts-1, 1) & HA_READ_PREV))
|
||||
reverse= 0; // Index can't be used
|
||||
}
|
||||
ok:
|
||||
if (used_key_parts != NULL)
|
||||
*used_key_parts= key_parts;
|
||||
DBUG_RETURN(reverse);
|
||||
}
|
||||
|
||||
@ -13303,7 +13391,6 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
|
||||
uint nr;
|
||||
uint min_length= (uint) ~0;
|
||||
uint best= MAX_KEY;
|
||||
uint not_used;
|
||||
KEY_PART_INFO *ref_key_part= table->key_info[ref].key_part;
|
||||
KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts;
|
||||
|
||||
@ -13314,7 +13401,7 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
|
||||
table->key_info[nr].key_parts >= ref_key_parts &&
|
||||
is_subkey(table->key_info[nr].key_part, ref_key_part,
|
||||
ref_key_part_end) &&
|
||||
test_if_order_by_key(order, table, nr, ¬_used))
|
||||
test_if_order_by_key(order, table, nr))
|
||||
{
|
||||
min_length= table->key_info[nr].key_length;
|
||||
best= nr;
|
||||
@ -13606,183 +13693,16 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
||||
goto check_reverse_order;
|
||||
}
|
||||
{
|
||||
/*
|
||||
Check whether there is an index compatible with the given order
|
||||
usage of which is cheaper than usage of the ref_key index (ref_key>=0)
|
||||
or a table scan.
|
||||
It may be the case if ORDER/GROUP BY is used with LIMIT.
|
||||
*/
|
||||
uint nr;
|
||||
key_map keys;
|
||||
uint best_key_parts= 0;
|
||||
int best_key_direction= 0;
|
||||
ha_rows best_records= 0;
|
||||
double read_time;
|
||||
int best_key= -1;
|
||||
bool is_best_covering= FALSE;
|
||||
double fanout= 1;
|
||||
JOIN *join= tab->join;
|
||||
uint tablenr= tab - join->join_tab;
|
||||
ha_rows table_records= table->file->stats.records;
|
||||
bool group= join->group && order == join->group_list;
|
||||
ha_rows ref_key_quick_rows= HA_POS_ERROR;
|
||||
|
||||
/*
|
||||
If not used with LIMIT, only use keys if the whole query can be
|
||||
resolved with a key; This is because filesort() is usually faster than
|
||||
retrieving all rows through an index.
|
||||
*/
|
||||
if (select_limit >= table_records)
|
||||
{
|
||||
keys= *table->file->keys_to_use_for_scanning();
|
||||
keys.merge(table->covering_keys);
|
||||
|
||||
/*
|
||||
We are adding here also the index specified in FORCE INDEX clause,
|
||||
if any.
|
||||
This is to allow users to use index in ORDER BY.
|
||||
*/
|
||||
if (table->force_index)
|
||||
keys.merge(group ? table->keys_in_use_for_group_by :
|
||||
table->keys_in_use_for_order_by);
|
||||
keys.intersect(usable_keys);
|
||||
}
|
||||
else
|
||||
keys= usable_keys;
|
||||
|
||||
if (ref_key >= 0 && table->covering_keys.is_set(ref_key))
|
||||
ref_key_quick_rows= table->quick_rows[ref_key];
|
||||
|
||||
read_time= join->best_positions[tablenr].read_time;
|
||||
for (uint i= tablenr+1; i < join->tables; i++)
|
||||
fanout*= join->best_positions[i].records_read; // fanout is always >= 1
|
||||
|
||||
for (nr=0; nr < table->s->keys ; nr++)
|
||||
{
|
||||
int direction;
|
||||
|
||||
if (keys.is_set(nr) &&
|
||||
(direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
|
||||
{
|
||||
/*
|
||||
At this point we are sure that ref_key is a non-ordering
|
||||
key (where "ordering key" is a key that will return rows
|
||||
in the order required by ORDER BY).
|
||||
*/
|
||||
DBUG_ASSERT (ref_key != (int) nr);
|
||||
|
||||
bool is_covering= table->covering_keys.is_set(nr) ||
|
||||
(nr == table->s->primary_key &&
|
||||
table->file->primary_key_is_clustered());
|
||||
|
||||
/*
|
||||
Don't use an index scan with ORDER BY without limit.
|
||||
For GROUP BY without limit always use index scan
|
||||
if there is a suitable index.
|
||||
Why we hold to this asymmetry hardly can be explained
|
||||
rationally. It's easy to demonstrate that using
|
||||
temporary table + filesort could be cheaper for grouping
|
||||
queries too.
|
||||
*/
|
||||
if (is_covering ||
|
||||
select_limit != HA_POS_ERROR ||
|
||||
(ref_key < 0 && (group || table->force_index)))
|
||||
{
|
||||
double rec_per_key;
|
||||
double index_scan_time;
|
||||
KEY *keyinfo= tab->table->key_info+nr;
|
||||
if (select_limit == HA_POS_ERROR)
|
||||
select_limit= table_records;
|
||||
if (group)
|
||||
{
|
||||
/*
|
||||
Used_key_parts can be larger than keyinfo->key_parts
|
||||
when using a secondary index clustered with a primary
|
||||
key (e.g. as in Innodb).
|
||||
See Bug #28591 for details.
|
||||
*/
|
||||
rec_per_key= used_key_parts &&
|
||||
used_key_parts <= keyinfo->key_parts ?
|
||||
keyinfo->rec_per_key[used_key_parts-1] : 1;
|
||||
set_if_bigger(rec_per_key, 1);
|
||||
/*
|
||||
With a grouping query each group containing on average
|
||||
rec_per_key records produces only one row that will
|
||||
be included into the result set.
|
||||
*/
|
||||
if (select_limit > table_records/rec_per_key)
|
||||
select_limit= table_records;
|
||||
else
|
||||
select_limit= (ha_rows) (select_limit*rec_per_key);
|
||||
}
|
||||
/*
|
||||
If tab=tk is not the last joined table tn then to get first
|
||||
L records from the result set we can expect to retrieve
|
||||
only L/fanout(tk,tn) where fanout(tk,tn) says how many
|
||||
rows in the record set on average will match each row tk.
|
||||
Usually our estimates for fanouts are too pessimistic.
|
||||
So the estimate for L/fanout(tk,tn) will be too optimistic
|
||||
and as result we'll choose an index scan when using ref/range
|
||||
access + filesort will be cheaper.
|
||||
*/
|
||||
select_limit= (ha_rows) (select_limit < fanout ?
|
||||
1 : select_limit/fanout);
|
||||
/*
|
||||
We assume that each of the tested indexes is not correlated
|
||||
with ref_key. Thus, to select first N records we have to scan
|
||||
N/selectivity(ref_key) index entries.
|
||||
selectivity(ref_key) = #scanned_records/#table_records =
|
||||
table->quick_condition_rows/table_records.
|
||||
In any case we can't select more than #table_records.
|
||||
N/(table->quick_condition_rows/table_records) > table_records
|
||||
<=> N > table->quick_condition_rows.
|
||||
*/
|
||||
if (select_limit > table->quick_condition_rows)
|
||||
select_limit= table_records;
|
||||
else
|
||||
select_limit= (ha_rows) (select_limit *
|
||||
(double) table_records /
|
||||
table->quick_condition_rows);
|
||||
rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1];
|
||||
set_if_bigger(rec_per_key, 1);
|
||||
/*
|
||||
Here we take into account the fact that rows are
|
||||
accessed in sequences rec_per_key records in each.
|
||||
Rows in such a sequence are supposed to be ordered
|
||||
by rowid/primary key. When reading the data
|
||||
in a sequence we'll touch not more pages than the
|
||||
table file contains.
|
||||
TODO. Use the formula for a disk sweep sequential access
|
||||
to calculate the cost of accessing data rows for one
|
||||
index entry.
|
||||
*/
|
||||
index_scan_time= select_limit/rec_per_key *
|
||||
min(rec_per_key, table->file->scan_time());
|
||||
if ((ref_key < 0 && is_covering) ||
|
||||
(ref_key < 0 && (group || table->force_index)) ||
|
||||
index_scan_time < read_time)
|
||||
{
|
||||
ha_rows quick_records= table_records;
|
||||
if ((is_best_covering && !is_covering) ||
|
||||
(is_covering && ref_key_quick_rows < select_limit))
|
||||
continue;
|
||||
if (table->quick_keys.is_set(nr))
|
||||
quick_records= table->quick_rows[nr];
|
||||
if (best_key < 0 ||
|
||||
(select_limit <= min(quick_records,best_records) ?
|
||||
keyinfo->key_parts < best_key_parts :
|
||||
quick_records < best_records))
|
||||
{
|
||||
best_key= nr;
|
||||
best_key_parts= keyinfo->key_parts;
|
||||
best_records= quick_records;
|
||||
is_best_covering= is_covering;
|
||||
best_key_direction= direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
test_if_cheaper_ordering(tab, order, table, usable_keys,
|
||||
ref_key, select_limit,
|
||||
&best_key, &best_key_direction,
|
||||
&select_limit, &best_key_parts);
|
||||
|
||||
/*
|
||||
filesort() and join cache are usually faster than reading in
|
||||
@ -13879,7 +13799,7 @@ check_reverse_order:
|
||||
*/
|
||||
if (!select->quick->reverse_sorted())
|
||||
{
|
||||
QUICK_SELECT_DESC *tmp;
|
||||
QUICK_SELECT_I *tmp;
|
||||
int quick_type= select->quick->get_type();
|
||||
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
|
||||
@ -13892,16 +13812,14 @@ check_reverse_order:
|
||||
}
|
||||
|
||||
/* ORDER BY range_key DESC */
|
||||
tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
|
||||
used_key_parts);
|
||||
if (!tmp || tmp->error)
|
||||
tmp= select->quick->make_reverse(used_key_parts);
|
||||
if (!tmp)
|
||||
{
|
||||
delete tmp;
|
||||
select->quick= save_quick;
|
||||
tab->limit= 0;
|
||||
DBUG_RETURN(0); // Reverse sort not supported
|
||||
}
|
||||
select->quick=tmp;
|
||||
select->set_quick(tmp);
|
||||
}
|
||||
}
|
||||
else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
|
||||
@ -17438,6 +17356,353 @@ void JOIN::cache_const_exprs()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Find a cheaper access key than a given @a key
|
||||
|
||||
@param tab NULL or JOIN_TAB of the accessed table
|
||||
@param order Linked list of ORDER BY arguments
|
||||
@param table Table if tab == NULL or tab->table
|
||||
@param usable_keys Key map to find a cheaper key in
|
||||
@param ref_key
|
||||
* 0 <= key < MAX_KEY - key number (hint) to start the search
|
||||
* -1 - no key number provided
|
||||
@param select_limit LIMIT value
|
||||
@param [out] new_key Key number if success, otherwise undefined
|
||||
@param [out] new_key_direction Return -1 (reverse) or +1 if success,
|
||||
otherwise undefined
|
||||
@param [out] new_select_limit Return adjusted LIMIT
|
||||
@param [out] new_used_key_parts NULL by default, otherwise return number
|
||||
of new_key prefix columns if success
|
||||
or undefined if the function fails
|
||||
|
||||
@note
|
||||
This function takes into account table->quick_condition_rows statistic
|
||||
(that is calculated by the make_join_statistics function).
|
||||
However, single table procedures such as mysql_update() and mysql_delete()
|
||||
never call make_join_statistics, so they have to update it manually
|
||||
(@see get_index_for_order()).
|
||||
*/
|
||||
|
||||
static bool
|
||||
test_if_cheaper_ordering(const JOIN_TAB *tab, ORDER *order, TABLE *table,
|
||||
key_map usable_keys, int ref_key,
|
||||
ha_rows select_limit,
|
||||
int *new_key, int *new_key_direction,
|
||||
ha_rows *new_select_limit, uint *new_used_key_parts)
|
||||
{
|
||||
DBUG_ENTER("test_if_cheaper_ordering");
|
||||
/*
|
||||
Check whether there is an index compatible with the given order
|
||||
usage of which is cheaper than usage of the ref_key index (ref_key>=0)
|
||||
or a table scan.
|
||||
It may be the case if ORDER/GROUP BY is used with LIMIT.
|
||||
*/
|
||||
ha_rows best_select_limit= HA_POS_ERROR;
|
||||
JOIN *join= tab ? tab->join : NULL;
|
||||
uint nr;
|
||||
key_map keys;
|
||||
uint best_key_parts= 0;
|
||||
int best_key_direction= 0;
|
||||
ha_rows best_records= 0;
|
||||
double read_time;
|
||||
int best_key= -1;
|
||||
bool is_best_covering= FALSE;
|
||||
double fanout= 1;
|
||||
ha_rows table_records= table->file->stats.records;
|
||||
bool group= join && join->group && order == join->group_list;
|
||||
ha_rows ref_key_quick_rows= HA_POS_ERROR;
|
||||
|
||||
/*
|
||||
If not used with LIMIT, only use keys if the whole query can be
|
||||
resolved with a key; This is because filesort() is usually faster than
|
||||
retrieving all rows through an index.
|
||||
*/
|
||||
if (select_limit >= table_records)
|
||||
{
|
||||
keys= *table->file->keys_to_use_for_scanning();
|
||||
keys.merge(table->covering_keys);
|
||||
|
||||
/*
|
||||
We are adding here also the index specified in FORCE INDEX clause,
|
||||
if any.
|
||||
This is to allow users to use index in ORDER BY.
|
||||
*/
|
||||
if (table->force_index)
|
||||
keys.merge(group ? table->keys_in_use_for_group_by :
|
||||
table->keys_in_use_for_order_by);
|
||||
keys.intersect(usable_keys);
|
||||
}
|
||||
else
|
||||
keys= usable_keys;
|
||||
|
||||
if (ref_key >= 0 && table->covering_keys.is_set(ref_key))
|
||||
ref_key_quick_rows= table->quick_rows[ref_key];
|
||||
|
||||
if (join)
|
||||
{
|
||||
uint tablenr= tab - join->join_tab;
|
||||
read_time= join->best_positions[tablenr].read_time;
|
||||
for (uint i= tablenr+1; i < join->tables; i++)
|
||||
fanout*= join->best_positions[i].records_read; // fanout is always >= 1
|
||||
}
|
||||
else
|
||||
read_time= table->file->scan_time();
|
||||
|
||||
for (nr=0; nr < table->s->keys ; nr++)
|
||||
{
|
||||
int direction;
|
||||
uint used_key_parts;
|
||||
|
||||
if (keys.is_set(nr) &&
|
||||
(direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
|
||||
{
|
||||
/*
|
||||
At this point we are sure that ref_key is a non-ordering
|
||||
key (where "ordering key" is a key that will return rows
|
||||
in the order required by ORDER BY).
|
||||
*/
|
||||
DBUG_ASSERT (ref_key != (int) nr);
|
||||
|
||||
bool is_covering= table->covering_keys.is_set(nr) ||
|
||||
(nr == table->s->primary_key &&
|
||||
table->file->primary_key_is_clustered());
|
||||
|
||||
/*
|
||||
Don't use an index scan with ORDER BY without limit.
|
||||
For GROUP BY without limit always use index scan
|
||||
if there is a suitable index.
|
||||
Why we hold to this asymmetry hardly can be explained
|
||||
rationally. It's easy to demonstrate that using
|
||||
temporary table + filesort could be cheaper for grouping
|
||||
queries too.
|
||||
*/
|
||||
if (is_covering ||
|
||||
select_limit != HA_POS_ERROR ||
|
||||
(ref_key < 0 && (group || table->force_index)))
|
||||
{
|
||||
double rec_per_key;
|
||||
double index_scan_time;
|
||||
KEY *keyinfo= table->key_info+nr;
|
||||
if (select_limit == HA_POS_ERROR)
|
||||
select_limit= table_records;
|
||||
if (group)
|
||||
{
|
||||
/*
|
||||
Used_key_parts can be larger than keyinfo->key_parts
|
||||
when using a secondary index clustered with a primary
|
||||
key (e.g. as in Innodb).
|
||||
See Bug #28591 for details.
|
||||
*/
|
||||
rec_per_key= used_key_parts &&
|
||||
used_key_parts <= keyinfo->key_parts ?
|
||||
keyinfo->rec_per_key[used_key_parts-1] : 1;
|
||||
set_if_bigger(rec_per_key, 1);
|
||||
/*
|
||||
With a grouping query each group containing on average
|
||||
rec_per_key records produces only one row that will
|
||||
be included into the result set.
|
||||
*/
|
||||
if (select_limit > table_records/rec_per_key)
|
||||
select_limit= table_records;
|
||||
else
|
||||
select_limit= (ha_rows) (select_limit*rec_per_key);
|
||||
}
|
||||
/*
|
||||
If tab=tk is not the last joined table tn then to get first
|
||||
L records from the result set we can expect to retrieve
|
||||
only L/fanout(tk,tn) where fanout(tk,tn) says how many
|
||||
rows in the record set on average will match each row tk.
|
||||
Usually our estimates for fanouts are too pessimistic.
|
||||
So the estimate for L/fanout(tk,tn) will be too optimistic
|
||||
and as result we'll choose an index scan when using ref/range
|
||||
access + filesort will be cheaper.
|
||||
*/
|
||||
select_limit= (ha_rows) (select_limit < fanout ?
|
||||
1 : select_limit/fanout);
|
||||
/*
|
||||
We assume that each of the tested indexes is not correlated
|
||||
with ref_key. Thus, to select first N records we have to scan
|
||||
N/selectivity(ref_key) index entries.
|
||||
selectivity(ref_key) = #scanned_records/#table_records =
|
||||
table->quick_condition_rows/table_records.
|
||||
In any case we can't select more than #table_records.
|
||||
N/(table->quick_condition_rows/table_records) > table_records
|
||||
<=> N > table->quick_condition_rows.
|
||||
*/
|
||||
if (select_limit > table->quick_condition_rows)
|
||||
select_limit= table_records;
|
||||
else
|
||||
select_limit= (ha_rows) (select_limit *
|
||||
(double) table_records /
|
||||
table->quick_condition_rows);
|
||||
rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1];
|
||||
set_if_bigger(rec_per_key, 1);
|
||||
/*
|
||||
Here we take into account the fact that rows are
|
||||
accessed in sequences rec_per_key records in each.
|
||||
Rows in such a sequence are supposed to be ordered
|
||||
by rowid/primary key. When reading the data
|
||||
in a sequence we'll touch not more pages than the
|
||||
table file contains.
|
||||
TODO. Use the formula for a disk sweep sequential access
|
||||
to calculate the cost of accessing data rows for one
|
||||
index entry.
|
||||
*/
|
||||
index_scan_time= select_limit/rec_per_key *
|
||||
min(rec_per_key, table->file->scan_time());
|
||||
if ((ref_key < 0 && is_covering) ||
|
||||
(ref_key < 0 && (group || table->force_index)) ||
|
||||
index_scan_time < read_time)
|
||||
{
|
||||
ha_rows quick_records= table_records;
|
||||
if ((is_best_covering && !is_covering) ||
|
||||
(is_covering && ref_key_quick_rows < select_limit))
|
||||
continue;
|
||||
if (table->quick_keys.is_set(nr))
|
||||
quick_records= table->quick_rows[nr];
|
||||
if (best_key < 0 ||
|
||||
(select_limit <= min(quick_records,best_records) ?
|
||||
keyinfo->key_parts < best_key_parts :
|
||||
quick_records < best_records))
|
||||
{
|
||||
best_key= nr;
|
||||
best_key_parts= keyinfo->key_parts;
|
||||
best_records= quick_records;
|
||||
is_best_covering= is_covering;
|
||||
best_key_direction= direction;
|
||||
best_select_limit= select_limit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (best_key < 0 || best_key == ref_key)
|
||||
DBUG_RETURN(FALSE);
|
||||
|
||||
*new_key= best_key;
|
||||
*new_key_direction= best_key_direction;
|
||||
*new_select_limit= best_select_limit;
|
||||
if (new_used_key_parts != NULL)
|
||||
*new_used_key_parts= best_key_parts;
|
||||
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Find a key to apply single table UPDATE/DELETE by a given ORDER
|
||||
|
||||
@param order Linked list of ORDER BY arguments
|
||||
@param table Table to find a key
|
||||
@param select Pointer to access/update select->quick (if any)
|
||||
@param limit LIMIT clause parameter
|
||||
@param [out] need_sort TRUE if filesort needed
|
||||
@param [out] reverse
|
||||
TRUE if the key is reversed again given ORDER (undefined if key == MAX_KEY)
|
||||
|
||||
@return
|
||||
- MAX_KEY if no key found (need_sort == TRUE)
|
||||
- MAX_KEY if quick select result order is OK (need_sort == FALSE)
|
||||
- key number (either index scan or quick select) (need_sort == FALSE)
|
||||
|
||||
@note
|
||||
Side effects:
|
||||
- may deallocate or deallocate and replace select->quick;
|
||||
- may set table->quick_condition_rows and table->quick_rows[...]
|
||||
to table->file->stats.records.
|
||||
*/
|
||||
|
||||
uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
|
||||
ha_rows limit, bool *need_sort, bool *reverse)
|
||||
{
|
||||
if (select && select->quick && select->quick->unique_key_range())
|
||||
{ // Single row select (always "ordered"): Ok to use with key field UPDATE
|
||||
*need_sort= FALSE;
|
||||
/*
|
||||
Returning of MAX_KEY here prevents updating of used_key_is_modified
|
||||
in mysql_update(). Use quick select "as is".
|
||||
*/
|
||||
return MAX_KEY;
|
||||
}
|
||||
|
||||
if (!order)
|
||||
{
|
||||
*need_sort= FALSE;
|
||||
if (select && select->quick)
|
||||
return select->quick->index; // index or MAX_KEY, use quick select as is
|
||||
else
|
||||
return table->file->key_used_on_scan; // MAX_KEY or index for some engines
|
||||
}
|
||||
|
||||
if (!is_simple_order(order)) // just to cut further expensive checks
|
||||
{
|
||||
*need_sort= TRUE;
|
||||
return MAX_KEY;
|
||||
}
|
||||
|
||||
if (select && select->quick)
|
||||
{
|
||||
if (select->quick->index == MAX_KEY)
|
||||
{
|
||||
*need_sort= TRUE;
|
||||
return MAX_KEY;
|
||||
}
|
||||
|
||||
uint used_key_parts;
|
||||
switch (test_if_order_by_key(order, table, select->quick->index,
|
||||
&used_key_parts)) {
|
||||
case 1: // desired order
|
||||
*need_sort= FALSE;
|
||||
return select->quick->index;
|
||||
case 0: // unacceptable order
|
||||
*need_sort= TRUE;
|
||||
return MAX_KEY;
|
||||
case -1: // desired order, but opposite direction
|
||||
{
|
||||
QUICK_SELECT_I *reverse_quick;
|
||||
if ((reverse_quick=
|
||||
select->quick->make_reverse(used_key_parts)))
|
||||
{
|
||||
select->set_quick(reverse_quick);
|
||||
*need_sort= FALSE;
|
||||
return select->quick->index;
|
||||
}
|
||||
else
|
||||
{
|
||||
*need_sort= TRUE;
|
||||
return MAX_KEY;
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(0);
|
||||
}
|
||||
else if (limit != HA_POS_ERROR)
|
||||
{ // check if some index scan & LIMIT is more efficient than filesort
|
||||
|
||||
/*
|
||||
Update quick_condition_rows since single table UPDATE/DELETE procedures
|
||||
don't call make_join_statistics() and leave this variable uninitialized.
|
||||
*/
|
||||
table->quick_condition_rows= table->file->stats.records;
|
||||
|
||||
int key, direction;
|
||||
if (test_if_cheaper_ordering(NULL, order, table,
|
||||
table->keys_in_use_for_order_by, -1,
|
||||
limit,
|
||||
&key, &direction, &limit) &&
|
||||
!is_key_used(table, key, table->write_set))
|
||||
{
|
||||
*need_sort= FALSE;
|
||||
*reverse= (direction < 0);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
*need_sort= TRUE;
|
||||
return MAX_KEY;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@} (end of group Query_Optimizer)
|
||||
*/
|
||||
|
@ -847,4 +847,12 @@ inline bool optimizer_flag(THD *thd, uint flag)
|
||||
return (thd->variables.optimizer_switch & flag);
|
||||
}
|
||||
|
||||
uint get_index_for_order(ORDER *order, TABLE *table, SQL_SELECT *select,
|
||||
ha_rows limit, bool *need_sort, bool *reverse);
|
||||
ORDER *simple_remove_const(ORDER *order, COND *where);
|
||||
bool const_expression_in_where(COND *cond, Item *comp_item,
|
||||
Field *comp_field= NULL,
|
||||
Item **const_item= NULL);
|
||||
|
||||
|
||||
#endif /* SQL_SELECT_INCLUDED */
|
||||
|
@ -4886,6 +4886,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
if (wait_while_table_is_used(thd, table->table,
|
||||
HA_EXTRA_PREPARE_FOR_RENAME))
|
||||
goto err;
|
||||
DEBUG_SYNC(thd, "after_admin_flush");
|
||||
/* Flush entries in the query cache involving this table. */
|
||||
query_cache_invalidate3(thd, table->table, 0);
|
||||
/*
|
||||
@ -5153,7 +5154,11 @@ send_result_message:
|
||||
{
|
||||
if (table->table->s->tmp_table)
|
||||
{
|
||||
if (open_for_modify)
|
||||
/*
|
||||
If the table was not opened successfully, do not try to get
|
||||
status information. (Bug#47633)
|
||||
*/
|
||||
if (open_for_modify && !open_error)
|
||||
table->table->file->info(HA_STATUS_CONST);
|
||||
}
|
||||
else if (open_for_modify || fatal_error)
|
||||
|
@ -203,12 +203,13 @@ int mysql_update(THD *thd,
|
||||
{
|
||||
bool using_limit= limit != HA_POS_ERROR;
|
||||
bool safe_update= test(thd->variables.option_bits & OPTION_SAFE_UPDATES);
|
||||
bool used_key_is_modified, transactional_table, will_batch;
|
||||
bool used_key_is_modified= FALSE, transactional_table, will_batch;
|
||||
bool can_compare_record;
|
||||
int res;
|
||||
int error, loc_error;
|
||||
uint used_index= MAX_KEY, dup_key_found;
|
||||
uint used_index, dup_key_found;
|
||||
bool need_sort= TRUE;
|
||||
bool reverse= FALSE;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
uint want_privilege;
|
||||
#endif
|
||||
@ -358,11 +359,7 @@ int mysql_update(THD *thd,
|
||||
my_ok(thd); // No matching records
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
if (!select && limit != HA_POS_ERROR)
|
||||
{
|
||||
if ((used_index= get_index_for_order(table, order, limit)) != MAX_KEY)
|
||||
need_sort= FALSE;
|
||||
}
|
||||
|
||||
/* If running in safe sql mode, don't allow updates without keys */
|
||||
if (table->quick_keys.is_clear_all())
|
||||
{
|
||||
@ -378,24 +375,20 @@ int mysql_update(THD *thd,
|
||||
|
||||
table->mark_columns_needed_for_update();
|
||||
|
||||
/* Check if we are modifying a key that we are used to search with */
|
||||
|
||||
if (select && select->quick)
|
||||
{
|
||||
used_index= select->quick->index;
|
||||
used_key_is_modified= (!select->quick->unique_key_range() &&
|
||||
select->quick->is_keys_used(table->write_set));
|
||||
table->update_const_key_parts(conds);
|
||||
order= simple_remove_const(order, conds);
|
||||
|
||||
used_index= get_index_for_order(order, table, select, limit,
|
||||
&need_sort, &reverse);
|
||||
if (need_sort)
|
||||
{ // Assign table scan index to check below for modified key fields:
|
||||
used_index= table->file->key_used_on_scan;
|
||||
}
|
||||
else
|
||||
{
|
||||
used_key_is_modified= 0;
|
||||
if (used_index == MAX_KEY) // no index for sort order
|
||||
used_index= table->file->key_used_on_scan;
|
||||
if (used_index != MAX_KEY)
|
||||
used_key_is_modified= is_key_used(table, used_index, table->write_set);
|
||||
if (used_index != MAX_KEY)
|
||||
{ // Check if we are modifying a key that we are used to search with:
|
||||
used_key_is_modified= is_key_used(table, used_index, table->write_set);
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
if (used_key_is_modified || order ||
|
||||
partition_key_modified(table, table->write_set))
|
||||
@ -414,7 +407,7 @@ int mysql_update(THD *thd,
|
||||
table->use_all_columns();
|
||||
}
|
||||
|
||||
/* note: We avoid sorting avoid if we sort on the used index */
|
||||
/* note: We avoid sorting if we sort on the used index */
|
||||
if (order && (need_sort || used_key_is_modified))
|
||||
{
|
||||
/*
|
||||
@ -476,7 +469,7 @@ int mysql_update(THD *thd,
|
||||
if (used_index == MAX_KEY || (select && select->quick))
|
||||
init_read_record(&info, thd, table, select, 0, 1, FALSE);
|
||||
else
|
||||
init_read_record_idx(&info, thd, table, 1, used_index);
|
||||
init_read_record_idx(&info, thd, table, 1, used_index, reverse);
|
||||
|
||||
thd_proc_info(thd, "Searching rows for update");
|
||||
ha_rows tmp_limit= limit;
|
||||
|
56
sql/table.cc
56
sql/table.cc
@ -33,6 +33,7 @@
|
||||
#include "sql_base.h" // release_table_share
|
||||
#include <m_ctype.h>
|
||||
#include "my_md5.h"
|
||||
#include "sql_select.h"
|
||||
|
||||
/* INFORMATION_SCHEMA name */
|
||||
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
|
||||
@ -4916,6 +4917,61 @@ void init_mdl_requests(TABLE_LIST *table_list)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Update TABLE::const_key_parts for single table UPDATE/DELETE query
|
||||
|
||||
@param conds WHERE clause expression
|
||||
|
||||
@retval TRUE error (OOM)
|
||||
@retval FALSE success
|
||||
|
||||
@note
|
||||
Set const_key_parts bits if key fields are equal to constants in
|
||||
the WHERE expression.
|
||||
*/
|
||||
|
||||
bool TABLE::update_const_key_parts(COND *conds)
|
||||
{
|
||||
bzero((char*) const_key_parts, sizeof(key_part_map) * s->keys);
|
||||
|
||||
if (conds == NULL)
|
||||
return FALSE;
|
||||
|
||||
for (uint index= 0; index < s->keys; index++)
|
||||
{
|
||||
KEY_PART_INFO *keyinfo= key_info[index].key_part;
|
||||
KEY_PART_INFO *keyinfo_end= keyinfo + key_info[index].key_parts;
|
||||
|
||||
for (key_part_map part_map= (key_part_map)1;
|
||||
keyinfo < keyinfo_end;
|
||||
keyinfo++, part_map<<= 1)
|
||||
{
|
||||
if (const_expression_in_where(conds, NULL, keyinfo->field))
|
||||
const_key_parts[index]|= part_map;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Test if the order list consists of simple field expressions
|
||||
|
||||
@param order Linked list of ORDER BY arguments
|
||||
|
||||
@return TRUE if @a order is empty or consist of simple field expressions
|
||||
*/
|
||||
|
||||
bool is_simple_order(ORDER *order)
|
||||
{
|
||||
for (ORDER *ord= order; ord; ord= ord->next)
|
||||
{
|
||||
if (ord->item[0]->real_item()->type() != Item::FIELD_ITEM)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
** Instansiate templates
|
||||
*****************************************************************************/
|
||||
|
@ -1104,6 +1104,8 @@ public:
|
||||
file->extra(HA_EXTRA_NO_KEYREAD);
|
||||
}
|
||||
}
|
||||
|
||||
bool update_const_key_parts(COND *conds);
|
||||
};
|
||||
|
||||
|
||||
@ -2088,6 +2090,8 @@ inline void mark_as_null_row(TABLE *table)
|
||||
bfill(table->null_flags,table->s->null_bytes,255);
|
||||
}
|
||||
|
||||
bool is_simple_order(ORDER *order);
|
||||
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
||||
#endif /* TABLE_INCLUDED */
|
||||
|
@ -419,9 +419,13 @@ bool trans_rollback_to_savepoint(THD *thd, LEX_STRING name)
|
||||
thd->transaction.savepoints= sv;
|
||||
|
||||
/*
|
||||
Release metadata locks that were acquired during this savepoint unit.
|
||||
Release metadata locks that were acquired during this savepoint unit
|
||||
unless binlogging is on. Releasing locks with binlogging on can break
|
||||
replication as it allows other connections to drop these tables before
|
||||
rollback to savepoint is written to the binlog.
|
||||
*/
|
||||
if (!res)
|
||||
bool binlog_on= mysql_bin_log.is_open() && thd->variables.sql_log_bin;
|
||||
if (!res && !binlog_on)
|
||||
thd->mdl_context.rollback_to_savepoint(sv->mdl_savepoint);
|
||||
|
||||
DBUG_RETURN(test(res));
|
||||
|
@ -1736,6 +1736,21 @@ err:
|
||||
{
|
||||
mysql_file_close(new_file, MYF(0));
|
||||
info->dfile=new_file= -1;
|
||||
/*
|
||||
On Windows, the old data file cannot be deleted if it is either
|
||||
open, or memory mapped. Closing the file won't remove the memory
|
||||
map implicilty on Windows. We closed the data file, but we keep
|
||||
the MyISAM table open. A memory map will be closed on the final
|
||||
mi_close() only. So we need to unmap explicitly here. After
|
||||
renaming the new file under the hook, we couldn't use the map of
|
||||
the old file any more anyway.
|
||||
*/
|
||||
if (info->s->file_map)
|
||||
{
|
||||
(void) my_munmap((char*) info->s->file_map,
|
||||
(size_t) info->s->mmaped_length);
|
||||
info->s->file_map= NULL;
|
||||
}
|
||||
if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
|
||||
DATA_TMP_EXT, share->base.raid_chunks,
|
||||
(param->testflag & T_BACKUP_DATA ?
|
||||
|
@ -103,6 +103,7 @@
|
||||
#include "myrg_def.h"
|
||||
#include "thr_malloc.h" // int_sql_alloc
|
||||
#include "sql_class.h" // THD
|
||||
#include "debug_sync.h"
|
||||
|
||||
static handler *myisammrg_create_handler(handlerton *hton,
|
||||
TABLE_SHARE *table,
|
||||
@ -755,6 +756,7 @@ int ha_myisammrg::attach_children(void)
|
||||
/* Must not call this with attached children. */
|
||||
DBUG_ASSERT(!this->file->children_attached);
|
||||
|
||||
DEBUG_SYNC(current_thd, "before_myisammrg_attach");
|
||||
/* Must call this with children list in place. */
|
||||
DBUG_ASSERT(this->table->pos_in_table_list->next_global == this->children_l);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user