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
|
# #Legacy option, maybe not needed anymore , taken as is from autotools build
|
||||||
# ADD_DEFINITIONS(-DNET_RETRY_COUNT=1000000)
|
# 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)
|
ADD_DEFINITIONS(/wd4996)
|
||||||
ENDIF()
|
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)
|
IF(CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||||
# _WIN64 is defined by the compiler itself.
|
# _WIN64 is defined by the compiler itself.
|
||||||
# Yet, we define it here again to work around a bug with Intellisense
|
# 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"
|
if test "$OSVERSION" -gt "600000"
|
||||||
then
|
then
|
||||||
# Post user-level threads, MYSQLD_NET_RETRY_COUNT is not needed any more
|
# 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" && \
|
elif test "$OSVERSION" -gt "480100" && \
|
||||||
test "$OSVERSION" -lt "500000" || \
|
test "$OSVERSION" -lt "500000" || \
|
||||||
test "$OSVERSION" -gt "500109"
|
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=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 --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 --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.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
|
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
|
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_heartbeat_2slaves # BUG#43828 2009-10-22 luis fails sporadically
|
||||||
rpl.rpl_innodb_bug28430* # Bug#46029
|
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
|
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
|
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.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
|
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.
|
# 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=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
|
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=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
|
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=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
|
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=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
|
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=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
|
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=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
|
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 $opt_reorder= shift; # True if we're reordering tests
|
||||||
my $suites= shift; # Semicolon separated list of test suites
|
my $suites= shift; # Semicolon separated list of test suites
|
||||||
my $opt_cases= shift;
|
my $opt_cases= shift;
|
||||||
|
my $opt_skip_test_list= shift;
|
||||||
my $cases= []; # Array of hash(one hash for each testcase)
|
my $cases= []; # Array of hash(one hash for each testcase)
|
||||||
|
|
||||||
$do_test_reg= init_pattern($do_test, "--do-test");
|
$do_test_reg= init_pattern($do_test, "--do-test");
|
||||||
@ -131,7 +132,7 @@ sub collect_test_cases ($$$) {
|
|||||||
{
|
{
|
||||||
foreach my $suite (split(",", $suites))
|
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;
|
last if $some_test_found;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -256,6 +257,7 @@ sub collect_one_suite($)
|
|||||||
{
|
{
|
||||||
my $suite= shift; # Test suite name
|
my $suite= shift; # Test suite name
|
||||||
my $opt_cases= shift;
|
my $opt_cases= shift;
|
||||||
|
my $opt_skip_test_list= shift;
|
||||||
my @cases; # Array of hash
|
my @cases; # Array of hash
|
||||||
|
|
||||||
mtr_verbose("Collecting: $suite");
|
mtr_verbose("Collecting: $suite");
|
||||||
@ -317,18 +319,23 @@ sub collect_one_suite($)
|
|||||||
# Build a hash of disabled testcases for this suite
|
# Build a hash of disabled testcases for this suite
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
my %disabled;
|
my %disabled;
|
||||||
if ( open(DISABLED, "$testdir/disabled.def" ) )
|
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 ) )
|
||||||
{
|
{
|
||||||
while ( <DISABLED> )
|
while ( <DISABLED> )
|
||||||
{
|
{
|
||||||
chomp;
|
chomp;
|
||||||
if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ )
|
if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ )
|
||||||
{
|
{
|
||||||
$disabled{$1}= $2;
|
$disabled{$1}= $2 if not exists $disabled{$1};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close DISABLED;
|
close DISABLED;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Read suite.opt file
|
# Read suite.opt file
|
||||||
my $suite_opt_file= "$testdir/suite.opt";
|
my $suite_opt_file= "$testdir/suite.opt";
|
||||||
|
@ -165,6 +165,7 @@ our @opt_extra_mysqld_opt;
|
|||||||
my $opt_compress;
|
my $opt_compress;
|
||||||
my $opt_ssl;
|
my $opt_ssl;
|
||||||
my $opt_skip_ssl;
|
my $opt_skip_ssl;
|
||||||
|
my @opt_skip_test_list;
|
||||||
our $opt_ssl_supported;
|
our $opt_ssl_supported;
|
||||||
my $opt_ps_protocol;
|
my $opt_ps_protocol;
|
||||||
my $opt_sp_protocol;
|
my $opt_sp_protocol;
|
||||||
@ -326,7 +327,7 @@ sub main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mtr_report("Collecting tests...");
|
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 ) {
|
if ( $opt_report_features ) {
|
||||||
# Put "report features" as the first test to run
|
# Put "report features" as the first test to run
|
||||||
@ -948,6 +949,7 @@ sub command_line_setup {
|
|||||||
|
|
||||||
'help|h' => \$opt_usage,
|
'help|h' => \$opt_usage,
|
||||||
'list-options' => \$opt_list_options,
|
'list-options' => \$opt_list_options,
|
||||||
|
'skip-test-list=s' => \@opt_skip_test_list
|
||||||
);
|
);
|
||||||
|
|
||||||
GetOptions(%options) or usage("Can't read options");
|
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
|
enable-disabled Run also tests marked as disabled
|
||||||
print-testcases Don't run the tests but print details about all the
|
print-testcases Don't run the tests but print details about all the
|
||||||
selected tests, in the order they would be run.
|
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
|
Options that specify ports
|
||||||
|
|
||||||
|
@ -333,7 +333,7 @@ rows_examined sql_text
|
|||||||
2 INSERT INTO t1 SELECT b+sleep(.01) from t2
|
2 INSERT INTO t1 SELECT b+sleep(.01) from t2
|
||||||
4 UPDATE t1 SET a=a+sleep(.01) WHERE a>2
|
4 UPDATE t1 SET a=a+sleep(.01) WHERE a>2
|
||||||
8 UPDATE t1 SET a=a+sleep(.01) ORDER BY a DESC
|
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)
|
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
|
6 DELETE FROM t1 WHERE a=a+sleep(.01) ORDER BY a LIMIT 2
|
||||||
DROP TABLE t1,t2;
|
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 `test_$1`;
|
DROP DATABASE IF EXISTS `test_$1`;
|
||||||
DROP DATABASE IF EXISTS mysqltest_LC2;
|
DROP DATABASE IF EXISTS mysqltest_LC2;
|
||||||
CREATE TABLE T1 (a int);
|
CREATE TABLE T1 (a int) ENGINE=MyISAM;
|
||||||
INSERT INTO T1 VALUES (1);
|
INSERT INTO T1 VALUES (1);
|
||||||
SHOW TABLES LIKE "T1";
|
SHOW TABLES LIKE "T1";
|
||||||
Tables_in_test (T1)
|
Tables_in_test (T1)
|
||||||
|
@ -1191,6 +1191,9 @@ SHOW CREATE TABLE t4;
|
|||||||
ERROR HY000: Table 't4' was not locked with LOCK TABLES
|
ERROR HY000: Table 't4' was not locked with LOCK TABLES
|
||||||
INSERT INTO t4 VALUES (4);
|
INSERT INTO t4 VALUES (4);
|
||||||
ERROR HY000: Table 't4' was not locked with LOCK TABLES
|
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;
|
CREATE TEMPORARY TABLE t4 LIKE t3;
|
||||||
SHOW CREATE TABLE t4;
|
SHOW CREATE TABLE t4;
|
||||||
ERROR HY000: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
|
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
|
33
|
||||||
DELETE FROM t4 WHERE c1 = 33;
|
DELETE FROM t4 WHERE c1 = 33;
|
||||||
DROP TRIGGER t3_ai;
|
DROP TRIGGER t3_ai;
|
||||||
|
UNLOCK TABLES;
|
||||||
#
|
#
|
||||||
# Trigger with table use on child
|
# Trigger with table use on child
|
||||||
DELETE FROM t4 WHERE c1 = 4;
|
DELETE FROM t4 WHERE c1 = 4;
|
||||||
@ -2635,6 +2639,17 @@ DROP TRIGGER t2_au;
|
|||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
DROP TABLE tm1, t1, t2, t3, t4, t5;
|
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
|
# Bug47098 assert in MDL_context::destroy on HANDLER
|
||||||
# <damaged merge table> OPEN
|
# <damaged merge table> OPEN
|
||||||
#
|
#
|
||||||
@ -2700,6 +2715,18 @@ ALTER TABLE m1 ADD INDEX (c1);
|
|||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
DROP TABLE m1, t1;
|
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"
|
# Test for bug #37371 "CREATE TABLE LIKE merge loses UNION parameter"
|
||||||
#
|
#
|
||||||
drop tables if exists t1, m1, m2;
|
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)
|
(SELECT 1 FROM t1,t2 WHERE t2.b > t3.b)
|
||||||
DROP TABLE t1,t2,t3;
|
DROP TABLE t1,t2,t3;
|
||||||
End of 5.0 tests.
|
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_key 0
|
||||||
Handler_read_next 0
|
Handler_read_next 0
|
||||||
Handler_read_prev 0
|
Handler_read_prev 0
|
||||||
Handler_read_rnd 1
|
Handler_read_rnd 0
|
||||||
Handler_read_rnd_next 9
|
Handler_read_rnd_next 0
|
||||||
alter table t1 disable keys;
|
alter table t1 disable keys;
|
||||||
flush status;
|
flush status;
|
||||||
delete from t1 order by a limit 1;
|
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;
|
DROP DATABASE IF EXISTS mysqltest_LC2;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
CREATE TABLE T1 (a int);
|
CREATE TABLE T1 (a int) ENGINE=MyISAM;
|
||||||
INSERT INTO T1 VALUES (1);
|
INSERT INTO T1 VALUES (1);
|
||||||
SHOW TABLES LIKE "T1";
|
SHOW TABLES LIKE "T1";
|
||||||
SHOW TABLES LIKE "t1";
|
SHOW TABLES LIKE "t1";
|
||||||
|
@ -457,7 +457,7 @@ CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t1);
|
|||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
DROP TABLE t1, t2;
|
DROP TABLE t1, t2;
|
||||||
CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3);
|
CREATE TABLE t2(a INT) ENGINE=MERGE UNION=(t3);
|
||||||
--error 1168
|
--error ER_WRONG_MRG_TABLE
|
||||||
SELECT * FROM t2;
|
SELECT * FROM t2;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
|
|
||||||
@ -549,11 +549,11 @@ drop table t1;
|
|||||||
# CREATE TABLE fails
|
# CREATE TABLE fails
|
||||||
#
|
#
|
||||||
CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2);
|
CREATE TABLE tm1(a INT) ENGINE=MERGE UNION=(t1, t2);
|
||||||
--error 1168
|
--error ER_WRONG_MRG_TABLE
|
||||||
SELECT * FROM tm1;
|
SELECT * FROM tm1;
|
||||||
CHECK TABLE tm1;
|
CHECK TABLE tm1;
|
||||||
CREATE TABLE t1(a INT);
|
CREATE TABLE t1(a INT);
|
||||||
--error 1168
|
--error ER_WRONG_MRG_TABLE
|
||||||
SELECT * FROM tm1;
|
SELECT * FROM tm1;
|
||||||
CHECK TABLE tm1;
|
CHECK TABLE tm1;
|
||||||
CREATE TABLE t2(a BLOB);
|
CREATE TABLE t2(a BLOB);
|
||||||
@ -887,6 +887,9 @@ CREATE TABLE t4 LIKE t3;
|
|||||||
SHOW CREATE TABLE t4;
|
SHOW CREATE TABLE t4;
|
||||||
--error ER_TABLE_NOT_LOCKED
|
--error ER_TABLE_NOT_LOCKED
|
||||||
INSERT INTO t4 VALUES (4);
|
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;
|
CREATE TEMPORARY TABLE t4 LIKE t3;
|
||||||
--error ER_WRONG_MRG_TABLE
|
--error ER_WRONG_MRG_TABLE
|
||||||
SHOW CREATE TABLE t4;
|
SHOW CREATE TABLE t4;
|
||||||
@ -913,7 +916,7 @@ DROP TABLE t4;
|
|||||||
--echo # 2. Normal rename.
|
--echo # 2. Normal rename.
|
||||||
SELECT * FROM t3 ORDER BY c1;
|
SELECT * FROM t3 ORDER BY c1;
|
||||||
RENAME TABLE t2 TO t5;
|
RENAME TABLE t2 TO t5;
|
||||||
--error 1168
|
--error ER_WRONG_MRG_TABLE
|
||||||
SELECT * FROM t3 ORDER BY c1;
|
SELECT * FROM t3 ORDER BY c1;
|
||||||
RENAME TABLE t5 TO t2;
|
RENAME TABLE t5 TO t2;
|
||||||
SELECT * FROM t3 ORDER BY c1;
|
SELECT * FROM t3 ORDER BY c1;
|
||||||
@ -931,7 +934,7 @@ UNLOCK TABLES;
|
|||||||
--echo #
|
--echo #
|
||||||
--echo # 4. Alter table rename.
|
--echo # 4. Alter table rename.
|
||||||
ALTER TABLE t2 RENAME TO t5;
|
ALTER TABLE t2 RENAME TO t5;
|
||||||
--error 1168
|
--error ER_WRONG_MRG_TABLE
|
||||||
SELECT * FROM t3 ORDER BY c1;
|
SELECT * FROM t3 ORDER BY c1;
|
||||||
ALTER TABLE t5 RENAME TO t2;
|
ALTER TABLE t5 RENAME TO t2;
|
||||||
SELECT * FROM t3 ORDER BY c1;
|
SELECT * FROM t3 ORDER BY c1;
|
||||||
@ -1170,6 +1173,7 @@ SELECT @a;
|
|||||||
SELECT * FROM t4 ORDER BY c1;
|
SELECT * FROM t4 ORDER BY c1;
|
||||||
DELETE FROM t4 WHERE c1 = 33;
|
DELETE FROM t4 WHERE c1 = 33;
|
||||||
DROP TRIGGER t3_ai;
|
DROP TRIGGER t3_ai;
|
||||||
|
UNLOCK TABLES;
|
||||||
--echo #
|
--echo #
|
||||||
--echo # Trigger with table use on child
|
--echo # Trigger with table use on child
|
||||||
DELETE FROM t4 WHERE c1 = 4;
|
DELETE FROM t4 WHERE c1 = 4;
|
||||||
@ -1273,6 +1277,7 @@ DROP TABLE t1, t2, t3;
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Bug#25038 - Waiting TRUNCATE
|
# 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.
|
# Show that truncate of child table after use of parent table works.
|
||||||
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
|
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
|
||||||
@ -1429,7 +1434,6 @@ FLUSH TABLES m1, t1;
|
|||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
DROP TABLE t1, m1;
|
DROP TABLE t1, m1;
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Bug#35068 - Assertion fails when reading from i_s.tables
|
# Bug#35068 - Assertion fails when reading from i_s.tables
|
||||||
# and there is incorrect merge table
|
# 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 t1 VALUES (1);
|
||||||
INSERT INTO mysql_test1.t2 VALUES (2);
|
INSERT INTO mysql_test1.t2 VALUES (2);
|
||||||
SELECT * FROM m1;
|
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 TABLE t1, mysql_test1.t2, m1;
|
||||||
DROP DATABASE mysql_test1;
|
DROP DATABASE mysql_test1;
|
||||||
#
|
#
|
||||||
@ -2104,6 +2108,14 @@ DROP TRIGGER t2_au;
|
|||||||
DROP FUNCTION f1;
|
DROP FUNCTION f1;
|
||||||
DROP TABLE tm1, t1, t2, t3, t4, t5;
|
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 #
|
||||||
--echo # Bug47098 assert in MDL_context::destroy on HANDLER
|
--echo # Bug47098 assert in MDL_context::destroy on HANDLER
|
||||||
--echo # <damaged merge table> OPEN
|
--echo # <damaged merge table> OPEN
|
||||||
@ -2186,6 +2198,18 @@ ALTER TABLE m1 ADD INDEX (c1);
|
|||||||
UNLOCK TABLES;
|
UNLOCK TABLES;
|
||||||
DROP TABLE m1, t1;
|
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 #
|
||||||
--echo # Test for bug #37371 "CREATE TABLE LIKE merge loses UNION parameter"
|
--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;
|
DROP TABLE t1,t2,t3;
|
||||||
|
|
||||||
--echo End of 5.0 tests.
|
--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;
|
||||||
|
@ -102,9 +102,19 @@ int nt_share_delete(const char *name, myf MyFlags)
|
|||||||
{
|
{
|
||||||
if (DeleteFile(buf))
|
if (DeleteFile(buf))
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
else if ((my_errno= GetLastError()) == 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
|
my_errno= ENOENT; // marking, that `buf' doesn't exist
|
||||||
} else
|
else
|
||||||
|
my_errno= errno;
|
||||||
|
}
|
||||||
|
else
|
||||||
my_errno= errno;
|
my_errno= errno;
|
||||||
|
|
||||||
if (MyFlags & (MY_FAE+MY_WME))
|
if (MyFlags & (MY_FAE+MY_WME))
|
||||||
|
@ -38,13 +38,16 @@ void *my_mmap(void *addr, size_t len, int prot,
|
|||||||
HANDLE hFileMap;
|
HANDLE hFileMap;
|
||||||
LPVOID ptr;
|
LPVOID ptr;
|
||||||
HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
|
HANDLE hFile= (HANDLE)my_get_osfhandle(fd);
|
||||||
|
DBUG_ENTER("my_mmap");
|
||||||
|
DBUG_PRINT("mysys", ("map fd: %d", fd));
|
||||||
|
|
||||||
if (hFile == INVALID_HANDLE_VALUE)
|
if (hFile == INVALID_HANDLE_VALUE)
|
||||||
return MAP_FAILED;
|
DBUG_RETURN(MAP_FAILED);
|
||||||
|
|
||||||
hFileMap=CreateFileMapping(hFile, &mmap_security_attributes,
|
hFileMap=CreateFileMapping(hFile, &mmap_security_attributes,
|
||||||
PAGE_READWRITE, 0, (DWORD) len, NULL);
|
PAGE_READWRITE, 0, (DWORD) len, NULL);
|
||||||
if (hFileMap == 0)
|
if (hFileMap == 0)
|
||||||
return MAP_FAILED;
|
DBUG_RETURN(MAP_FAILED);
|
||||||
|
|
||||||
ptr=MapViewOfFile(hFileMap,
|
ptr=MapViewOfFile(hFileMap,
|
||||||
prot & PROT_WRITE ? FILE_MAP_WRITE : FILE_MAP_READ,
|
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);
|
CloseHandle(hFileMap);
|
||||||
|
|
||||||
if (ptr)
|
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)
|
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)
|
int my_msync(int fd, void *addr, size_t len, int flags)
|
||||||
|
@ -51,6 +51,7 @@
|
|||||||
#include "sp_rcontext.h"
|
#include "sp_rcontext.h"
|
||||||
#include "sp.h"
|
#include "sp.h"
|
||||||
#include "set_var.h"
|
#include "set_var.h"
|
||||||
|
#include "debug_sync.h"
|
||||||
|
|
||||||
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
#ifdef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
#define sp_restore_security_context(A,B) while (0) {}
|
#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()
|
double Item_func_acos::val_real()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
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)
|
// the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug)
|
||||||
volatile double value= args[0]->val_real();
|
volatile double value= args[0]->val_real();
|
||||||
if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
|
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
|
Table rows retrieval plan. Range optimizer creates QUICK_SELECT_I-derived
|
||||||
objects from table read plans.
|
objects from table read plans.
|
||||||
@ -8977,7 +8887,6 @@ QUICK_SELECT_DESC::QUICK_SELECT_DESC(QUICK_RANGE_SELECT *q,
|
|||||||
}
|
}
|
||||||
rev_it.rewind();
|
rev_it.rewind();
|
||||||
q->dont_free=1; // Don't free shared mem
|
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
|
Compare if found key is over max-value
|
||||||
Returns 0 if key <= range->max_key
|
Returns 0 if key <= range->max_key
|
||||||
@ -11673,6 +11603,7 @@ void QUICK_RANGE_SELECT::dbug_dump(int indent, bool verbose)
|
|||||||
/* purecov: end */
|
/* purecov: end */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
|
void QUICK_INDEX_MERGE_SELECT::dbug_dump(int indent, bool verbose)
|
||||||
{
|
{
|
||||||
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
|
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
|
** Instantiate templates
|
||||||
|
@ -352,6 +352,11 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void dbug_dump(int indent, bool verbose)= 0;
|
virtual void dbug_dump(int indent, bool verbose)= 0;
|
||||||
#endif
|
#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
|
#ifndef DBUG_OFF
|
||||||
void dbug_dump(int indent, bool verbose);
|
void dbug_dump(int indent, bool verbose);
|
||||||
#endif
|
#endif
|
||||||
|
QUICK_SELECT_I *make_reverse(uint used_key_parts_arg);
|
||||||
private:
|
private:
|
||||||
/* Default copy ctor used by QUICK_SELECT_DESC */
|
/* Default copy ctor used by QUICK_SELECT_DESC */
|
||||||
};
|
};
|
||||||
@ -782,6 +788,10 @@ public:
|
|||||||
int get_next();
|
int get_next();
|
||||||
bool reverse_sorted() { return 1; }
|
bool reverse_sorted() { return 1; }
|
||||||
int get_type() { return QS_TYPE_RANGE_DESC; }
|
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:
|
private:
|
||||||
bool range_reads_after_key(QUICK_RANGE *range);
|
bool range_reads_after_key(QUICK_RANGE *range);
|
||||||
int reset(void) { rev_it.rewind(); return QUICK_RANGE_SELECT::reset(); }
|
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();
|
||||||
~SQL_SELECT();
|
~SQL_SELECT();
|
||||||
void cleanup();
|
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)
|
bool check_quick(THD *thd, bool force_quick_range, ha_rows limit)
|
||||||
{
|
{
|
||||||
key_map tmp;
|
key_map tmp;
|
||||||
@ -833,7 +844,6 @@ public:
|
|||||||
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
|
QUICK_RANGE_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
|
||||||
struct st_table_ref *ref,
|
struct st_table_ref *ref,
|
||||||
ha_rows records);
|
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,
|
SQL_SELECT *make_select(TABLE *head, table_map const_tables,
|
||||||
table_map read_tables, COND *conds,
|
table_map read_tables, COND *conds,
|
||||||
bool allow_null_cond, int *error);
|
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 init_rr_cache(THD *thd, READ_RECORD *info);
|
||||||
static int rr_cmp(uchar *a,uchar *b);
|
static int rr_cmp(uchar *a,uchar *b);
|
||||||
static int rr_index_first(READ_RECORD *info);
|
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(READ_RECORD *info);
|
||||||
|
static int rr_index_desc(READ_RECORD *info);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize READ_RECORD structure to perform full index scan (in forward
|
Initialize READ_RECORD structure to perform full index scan in desired
|
||||||
direction) using read_record.read_record() interface.
|
direction using read_record.read_record() interface
|
||||||
|
|
||||||
This function has been added at late stage and is used only by
|
This function has been added at late stage and is used only by
|
||||||
UPDATE/DELETE. Other statements perform index scans using
|
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
|
@param print_error If true, call table->file->print_error() if an error
|
||||||
occurs (except for end-of-records error)
|
occurs (except for end-of-records error)
|
||||||
@param idx index to scan
|
@param idx index to scan
|
||||||
|
@param reverse Scan in the reverse direction
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
|
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);
|
empty_record(table);
|
||||||
bzero((char*) info,sizeof(*info));
|
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)
|
if (!table->file->inited)
|
||||||
table->file->ha_index_init(idx, 1);
|
table->file->ha_index_init(idx, 1);
|
||||||
/* read_record will be changed to rr_index in rr_index_first */
|
/* 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.
|
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 rr_sequential(READ_RECORD *info)
|
||||||
{
|
{
|
||||||
int tmp;
|
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,
|
SQL_SELECT *select, int use_record_cache,
|
||||||
bool print_errors, bool disable_rr_cache);
|
bool print_errors, bool disable_rr_cache);
|
||||||
void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
|
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 end_read_record(READ_RECORD *info);
|
||||||
|
|
||||||
void rr_unlock_row(st_join_table *tab);
|
void rr_unlock_row(st_join_table *tab);
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
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;
|
bool will_batch;
|
||||||
int error, loc_error;
|
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 transactional_table, safe_update, const_cond;
|
||||||
bool const_cond_result;
|
bool const_cond_result;
|
||||||
ha_rows deleted= 0;
|
ha_rows deleted= 0;
|
||||||
|
bool reverse= FALSE;
|
||||||
|
ORDER *order= (ORDER *) ((order_list && order_list->elements) ?
|
||||||
|
order_list->first : NULL);
|
||||||
uint usable_index= MAX_KEY;
|
uint usable_index= MAX_KEY;
|
||||||
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
SELECT_LEX *select_lex= &thd->lex->select_lex;
|
||||||
THD::killed_state killed_status= THD::NOT_KILLED;
|
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);
|
DBUG_RETURN(TRUE);
|
||||||
|
|
||||||
/* check ORDER BY even if it can be ignored */
|
/* check ORDER BY even if it can be ignored */
|
||||||
if (order && order->elements)
|
if (order)
|
||||||
{
|
{
|
||||||
TABLE_LIST tables;
|
TABLE_LIST tables;
|
||||||
List<Item> fields;
|
List<Item> fields;
|
||||||
@ -89,9 +92,9 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
tables.table = table;
|
tables.table = table;
|
||||||
tables.alias = table_list->alias;
|
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,
|
setup_order(thd, select_lex->ref_pointer_array, &tables,
|
||||||
fields, all_fields, order->first))
|
fields, all_fields, order))
|
||||||
{
|
{
|
||||||
delete select;
|
delete select;
|
||||||
free_underlaid_joins(thd, &thd->lex->select_lex);
|
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->covering_keys.clear_all();
|
||||||
table->quick_keys.clear_all(); // Can't use 'only index'
|
table->quick_keys.clear_all(); // Can't use 'only index'
|
||||||
|
|
||||||
select=make_select(table, 0, 0, conds, 0, &error);
|
select=make_select(table, 0, 0, conds, 0, &error);
|
||||||
if (error)
|
if (error)
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
@ -217,22 +221,25 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
|||||||
if (options & OPTION_QUICK)
|
if (options & OPTION_QUICK)
|
||||||
(void) table->file->extra(HA_EXTRA_QUICK);
|
(void) table->file->extra(HA_EXTRA_QUICK);
|
||||||
|
|
||||||
if (order && order->elements)
|
if (order)
|
||||||
{
|
{
|
||||||
uint length= 0;
|
uint length= 0;
|
||||||
SORT_FIELD *sortorder;
|
SORT_FIELD *sortorder;
|
||||||
ha_rows examined_rows;
|
ha_rows examined_rows;
|
||||||
|
|
||||||
if ((!select || table->quick_keys.is_clear_all()) && limit != HA_POS_ERROR)
|
table->update_const_key_parts(conds);
|
||||||
usable_index= get_index_for_order(table, order->first, limit);
|
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),
|
table->sort.io_cache= (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
|
||||||
MYF(MY_FAE | MY_ZEROFILL));
|
MYF(MY_FAE | MY_ZEROFILL));
|
||||||
|
|
||||||
if (!(sortorder= make_unireg_sortorder(order->first,
|
if (!(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
|
||||||
&length, NULL)) ||
|
|
||||||
(table->sort.found_records = filesort(thd, table, sortorder, length,
|
(table->sort.found_records = filesort(thd, table, sortorder, length,
|
||||||
select, HA_POS_ERROR, 1,
|
select, HA_POS_ERROR, 1,
|
||||||
&examined_rows))
|
&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))
|
if (usable_index==MAX_KEY || (select && select->quick))
|
||||||
init_read_record(&info, thd, table, select, 1, 1, FALSE);
|
init_read_record(&info, thd, table, select, 1, 1, FALSE);
|
||||||
else
|
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);
|
init_ftfuncs(thd, select_lex, 1);
|
||||||
thd_proc_info(thd, "updating");
|
thd_proc_info(thd, "updating");
|
||||||
|
@ -998,7 +998,7 @@ extern const LEX_STRING null_lex_str;
|
|||||||
extern const LEX_STRING empty_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
|
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,
|
static COND *optimize_cond(JOIN *join, COND *conds,
|
||||||
List<TABLE_LIST> *join_list,
|
List<TABLE_LIST> *join_list,
|
||||||
Item::cond_result *cond_value);
|
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 open_tmp_table(TABLE *table);
|
||||||
static bool create_myisam_tmp_table(TABLE *,TMP_TABLE_PARAM *, ulonglong, my_bool);
|
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,
|
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);
|
table_map used_table);
|
||||||
static Item* part_of_refkey(TABLE *form,Field *field);
|
static Item* part_of_refkey(TABLE *form,Field *field);
|
||||||
uint find_shortest_key(TABLE *table, const key_map *usable_keys);
|
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,
|
static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
|
||||||
ha_rows select_limit, bool no_changes,
|
ha_rows select_limit, bool no_changes,
|
||||||
key_map *map);
|
key_map *map);
|
||||||
@ -7361,8 +7367,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond,
|
|||||||
*simple_order=0;
|
*simple_order=0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Item *comp_item=0;
|
if (cond && const_expression_in_where(cond,order->item[0]))
|
||||||
if (cond && const_expression_in_where(cond,order->item[0], &comp_item))
|
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
|
DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
|
||||||
continue;
|
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
|
static int
|
||||||
return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
|
return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
|
||||||
List<Item> &fields, bool send_row, ulonglong select_options,
|
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))
|
left_item->collation.collation == value->collation.collation))
|
||||||
{
|
{
|
||||||
Item *tmp=value->clone_item();
|
Item *tmp=value->clone_item();
|
||||||
tmp->collation.set(right_item->collation);
|
|
||||||
|
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
|
tmp->collation.set(right_item->collation);
|
||||||
thd->change_item_tree(args + 1, tmp);
|
thd->change_item_tree(args + 1, tmp);
|
||||||
func->update_used_tables();
|
func->update_used_tables();
|
||||||
if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
|
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))
|
right_item->collation.collation == value->collation.collation))
|
||||||
{
|
{
|
||||||
Item *tmp= value->clone_item();
|
Item *tmp= value->clone_item();
|
||||||
tmp->collation.set(left_item->collation);
|
|
||||||
|
|
||||||
if (tmp)
|
if (tmp)
|
||||||
{
|
{
|
||||||
|
tmp->collation.set(left_item->collation);
|
||||||
thd->change_item_tree(args, tmp);
|
thd->change_item_tree(args, tmp);
|
||||||
value= tmp;
|
value= tmp;
|
||||||
func->update_used_tables();
|
func->update_used_tables();
|
||||||
@ -9593,13 +9636,50 @@ test_if_equality_guarantees_uniqueness(Item *l, Item *r)
|
|||||||
l->collation.collation == r->collation.collation)));
|
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
|
static bool equal(Item *i1, Item *i2, Field *f2)
|
||||||
const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
|
|
||||||
{
|
{
|
||||||
|
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)
|
if (cond->type() == Item::COND_ITEM)
|
||||||
{
|
{
|
||||||
bool and_level= (((Item_cond*) cond)->functype()
|
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;
|
Item *item;
|
||||||
while ((item=li++))
|
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 (res) // Is a const value
|
||||||
{
|
{
|
||||||
if (and_level)
|
if (and_level)
|
||||||
@ -9620,14 +9701,14 @@ const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
|
|||||||
return and_level ? 0 : 1;
|
return and_level ? 0 : 1;
|
||||||
}
|
}
|
||||||
else if (cond->eq_cmp_result() != Item::COND_OK)
|
else if (cond->eq_cmp_result() != Item::COND_OK)
|
||||||
{ // boolan compare function
|
{ // boolean compare function
|
||||||
Item_func* func= (Item_func*) cond;
|
Item_func* func= (Item_func*) cond;
|
||||||
if (func->functype() != Item_func::EQUAL_FUNC &&
|
if (func->functype() != Item_func::EQUAL_FUNC &&
|
||||||
func->functype() != Item_func::EQ_FUNC)
|
func->functype() != Item_func::EQ_FUNC)
|
||||||
return 0;
|
return 0;
|
||||||
Item *left_item= ((Item_func*) cond)->arguments()[0];
|
Item *left_item= ((Item_func*) cond)->arguments()[0];
|
||||||
Item *right_item= ((Item_func*) cond)->arguments()[1];
|
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))
|
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;
|
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))
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Create internal temporary table
|
Create internal temporary table
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -13104,7 +13186,8 @@ part_of_refkey(TABLE *table,Field *field)
|
|||||||
@param order Sort order
|
@param order Sort order
|
||||||
@param table Table to sort
|
@param table Table to sort
|
||||||
@param idx Index to check
|
@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
|
@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,
|
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_INFO *key_part,*key_part_end;
|
||||||
key_part=table->key_info[idx].key_part;
|
key_part=table->key_info[idx].key_part;
|
||||||
key_part_end=key_part+table->key_info[idx].key_parts;
|
key_part_end=key_part+table->key_info[idx].key_parts;
|
||||||
key_part_map const_key_parts=table->const_key_parts[idx];
|
key_part_map const_key_parts=table->const_key_parts[idx];
|
||||||
int reverse=0;
|
int reverse=0;
|
||||||
|
uint key_parts;
|
||||||
my_bool on_pk_suffix= FALSE;
|
my_bool on_pk_suffix= FALSE;
|
||||||
DBUG_ENTER("test_if_order_by_key");
|
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)
|
if (key_part == key_part_end && reverse == 0)
|
||||||
{
|
{
|
||||||
*used_key_parts= 0;
|
key_parts= 0;
|
||||||
DBUG_RETURN(1);
|
reverse= 1;
|
||||||
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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_secondary= table->key_info[idx].key_parts;
|
||||||
uint used_key_parts_pk=
|
uint used_key_parts_pk=
|
||||||
(uint) (key_part - table->key_info[table->s->primary_key].key_part);
|
(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 &&
|
if (reverse == -1 &&
|
||||||
(!(table->file->index_flags(idx, used_key_parts_secondary - 1, 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
|
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 &&
|
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
|
reverse= 0; // Index can't be used
|
||||||
}
|
}
|
||||||
|
ok:
|
||||||
|
if (used_key_parts != NULL)
|
||||||
|
*used_key_parts= key_parts;
|
||||||
DBUG_RETURN(reverse);
|
DBUG_RETURN(reverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -13303,7 +13391,6 @@ test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
|
|||||||
uint nr;
|
uint nr;
|
||||||
uint min_length= (uint) ~0;
|
uint min_length= (uint) ~0;
|
||||||
uint best= MAX_KEY;
|
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= table->key_info[ref].key_part;
|
||||||
KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts;
|
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 &&
|
table->key_info[nr].key_parts >= ref_key_parts &&
|
||||||
is_subkey(table->key_info[nr].key_part, ref_key_part,
|
is_subkey(table->key_info[nr].key_part, ref_key_part,
|
||||||
ref_key_part_end) &&
|
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;
|
min_length= table->key_info[nr].key_length;
|
||||||
best= nr;
|
best= nr;
|
||||||
@ -13606,183 +13693,16 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||||||
goto check_reverse_order;
|
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;
|
uint best_key_parts= 0;
|
||||||
int best_key_direction= 0;
|
int best_key_direction= 0;
|
||||||
ha_rows best_records= 0;
|
|
||||||
double read_time;
|
|
||||||
int best_key= -1;
|
int best_key= -1;
|
||||||
bool is_best_covering= FALSE;
|
|
||||||
double fanout= 1;
|
|
||||||
JOIN *join= tab->join;
|
JOIN *join= tab->join;
|
||||||
uint tablenr= tab - join->join_tab;
|
|
||||||
ha_rows table_records= table->file->stats.records;
|
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;
|
|
||||||
|
|
||||||
/*
|
test_if_cheaper_ordering(tab, order, table, usable_keys,
|
||||||
If not used with LIMIT, only use keys if the whole query can be
|
ref_key, select_limit,
|
||||||
resolved with a key; This is because filesort() is usually faster than
|
&best_key, &best_key_direction,
|
||||||
retrieving all rows through an index.
|
&select_limit, &best_key_parts);
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
filesort() and join cache are usually faster than reading in
|
filesort() and join cache are usually faster than reading in
|
||||||
@ -13879,7 +13799,7 @@ check_reverse_order:
|
|||||||
*/
|
*/
|
||||||
if (!select->quick->reverse_sorted())
|
if (!select->quick->reverse_sorted())
|
||||||
{
|
{
|
||||||
QUICK_SELECT_DESC *tmp;
|
QUICK_SELECT_I *tmp;
|
||||||
int quick_type= select->quick->get_type();
|
int quick_type= select->quick->get_type();
|
||||||
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
|
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
|
||||||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
|
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
|
||||||
@ -13892,16 +13812,14 @@ check_reverse_order:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ORDER BY range_key DESC */
|
/* ORDER BY range_key DESC */
|
||||||
tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
|
tmp= select->quick->make_reverse(used_key_parts);
|
||||||
used_key_parts);
|
if (!tmp)
|
||||||
if (!tmp || tmp->error)
|
|
||||||
{
|
{
|
||||||
delete tmp;
|
|
||||||
select->quick= save_quick;
|
select->quick= save_quick;
|
||||||
tab->limit= 0;
|
tab->limit= 0;
|
||||||
DBUG_RETURN(0); // Reverse sort not supported
|
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 &&
|
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)
|
@} (end of group Query_Optimizer)
|
||||||
*/
|
*/
|
||||||
|
@ -847,4 +847,12 @@ inline bool optimizer_flag(THD *thd, uint flag)
|
|||||||
return (thd->variables.optimizer_switch & 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 */
|
#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,
|
if (wait_while_table_is_used(thd, table->table,
|
||||||
HA_EXTRA_PREPARE_FOR_RENAME))
|
HA_EXTRA_PREPARE_FOR_RENAME))
|
||||||
goto err;
|
goto err;
|
||||||
|
DEBUG_SYNC(thd, "after_admin_flush");
|
||||||
/* Flush entries in the query cache involving this table. */
|
/* Flush entries in the query cache involving this table. */
|
||||||
query_cache_invalidate3(thd, table->table, 0);
|
query_cache_invalidate3(thd, table->table, 0);
|
||||||
/*
|
/*
|
||||||
@ -5153,7 +5154,11 @@ send_result_message:
|
|||||||
{
|
{
|
||||||
if (table->table->s->tmp_table)
|
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);
|
table->table->file->info(HA_STATUS_CONST);
|
||||||
}
|
}
|
||||||
else if (open_for_modify || fatal_error)
|
else if (open_for_modify || fatal_error)
|
||||||
|
@ -203,12 +203,13 @@ int mysql_update(THD *thd,
|
|||||||
{
|
{
|
||||||
bool using_limit= limit != HA_POS_ERROR;
|
bool using_limit= limit != HA_POS_ERROR;
|
||||||
bool safe_update= test(thd->variables.option_bits & OPTION_SAFE_UPDATES);
|
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;
|
bool can_compare_record;
|
||||||
int res;
|
int res;
|
||||||
int error, loc_error;
|
int error, loc_error;
|
||||||
uint used_index= MAX_KEY, dup_key_found;
|
uint used_index, dup_key_found;
|
||||||
bool need_sort= TRUE;
|
bool need_sort= TRUE;
|
||||||
|
bool reverse= FALSE;
|
||||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||||
uint want_privilege;
|
uint want_privilege;
|
||||||
#endif
|
#endif
|
||||||
@ -358,11 +359,7 @@ int mysql_update(THD *thd,
|
|||||||
my_ok(thd); // No matching records
|
my_ok(thd); // No matching records
|
||||||
DBUG_RETURN(0);
|
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 running in safe sql mode, don't allow updates without keys */
|
||||||
if (table->quick_keys.is_clear_all())
|
if (table->quick_keys.is_clear_all())
|
||||||
{
|
{
|
||||||
@ -378,24 +375,20 @@ int mysql_update(THD *thd,
|
|||||||
|
|
||||||
table->mark_columns_needed_for_update();
|
table->mark_columns_needed_for_update();
|
||||||
|
|
||||||
/* Check if we are modifying a key that we are used to search with */
|
table->update_const_key_parts(conds);
|
||||||
|
order= simple_remove_const(order, conds);
|
||||||
|
|
||||||
if (select && select->quick)
|
used_index= get_index_for_order(order, table, select, limit,
|
||||||
{
|
&need_sort, &reverse);
|
||||||
used_index= select->quick->index;
|
if (need_sort)
|
||||||
used_key_is_modified= (!select->quick->unique_key_range() &&
|
{ // Assign table scan index to check below for modified key fields:
|
||||||
select->quick->is_keys_used(table->write_set));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
used_key_is_modified= 0;
|
|
||||||
if (used_index == MAX_KEY) // no index for sort order
|
|
||||||
used_index= table->file->key_used_on_scan;
|
used_index= table->file->key_used_on_scan;
|
||||||
|
}
|
||||||
if (used_index != MAX_KEY)
|
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);
|
used_key_is_modified= is_key_used(table, used_index, table->write_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||||
if (used_key_is_modified || order ||
|
if (used_key_is_modified || order ||
|
||||||
partition_key_modified(table, table->write_set))
|
partition_key_modified(table, table->write_set))
|
||||||
@ -414,7 +407,7 @@ int mysql_update(THD *thd,
|
|||||||
table->use_all_columns();
|
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))
|
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))
|
if (used_index == MAX_KEY || (select && select->quick))
|
||||||
init_read_record(&info, thd, table, select, 0, 1, FALSE);
|
init_read_record(&info, thd, table, select, 0, 1, FALSE);
|
||||||
else
|
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");
|
thd_proc_info(thd, "Searching rows for update");
|
||||||
ha_rows tmp_limit= limit;
|
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 "sql_base.h" // release_table_share
|
||||||
#include <m_ctype.h>
|
#include <m_ctype.h>
|
||||||
#include "my_md5.h"
|
#include "my_md5.h"
|
||||||
|
#include "sql_select.h"
|
||||||
|
|
||||||
/* INFORMATION_SCHEMA name */
|
/* INFORMATION_SCHEMA name */
|
||||||
LEX_STRING INFORMATION_SCHEMA_NAME= {C_STRING_WITH_LEN("information_schema")};
|
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
|
** Instansiate templates
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
@ -1104,6 +1104,8 @@ public:
|
|||||||
file->extra(HA_EXTRA_NO_KEYREAD);
|
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);
|
bfill(table->null_flags,table->s->null_bytes,255);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_simple_order(ORDER *order);
|
||||||
|
|
||||||
#endif /* MYSQL_CLIENT */
|
#endif /* MYSQL_CLIENT */
|
||||||
|
|
||||||
#endif /* TABLE_INCLUDED */
|
#endif /* TABLE_INCLUDED */
|
||||||
|
@ -419,9 +419,13 @@ bool trans_rollback_to_savepoint(THD *thd, LEX_STRING name)
|
|||||||
thd->transaction.savepoints= sv;
|
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);
|
thd->mdl_context.rollback_to_savepoint(sv->mdl_savepoint);
|
||||||
|
|
||||||
DBUG_RETURN(test(res));
|
DBUG_RETURN(test(res));
|
||||||
|
@ -1736,6 +1736,21 @@ err:
|
|||||||
{
|
{
|
||||||
mysql_file_close(new_file, MYF(0));
|
mysql_file_close(new_file, MYF(0));
|
||||||
info->dfile=new_file= -1;
|
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,
|
if (change_to_newfile(share->data_file_name,MI_NAME_DEXT,
|
||||||
DATA_TMP_EXT, share->base.raid_chunks,
|
DATA_TMP_EXT, share->base.raid_chunks,
|
||||||
(param->testflag & T_BACKUP_DATA ?
|
(param->testflag & T_BACKUP_DATA ?
|
||||||
|
@ -103,6 +103,7 @@
|
|||||||
#include "myrg_def.h"
|
#include "myrg_def.h"
|
||||||
#include "thr_malloc.h" // int_sql_alloc
|
#include "thr_malloc.h" // int_sql_alloc
|
||||||
#include "sql_class.h" // THD
|
#include "sql_class.h" // THD
|
||||||
|
#include "debug_sync.h"
|
||||||
|
|
||||||
static handler *myisammrg_create_handler(handlerton *hton,
|
static handler *myisammrg_create_handler(handlerton *hton,
|
||||||
TABLE_SHARE *table,
|
TABLE_SHARE *table,
|
||||||
@ -755,6 +756,7 @@ int ha_myisammrg::attach_children(void)
|
|||||||
/* Must not call this with attached children. */
|
/* Must not call this with attached children. */
|
||||||
DBUG_ASSERT(!this->file->children_attached);
|
DBUG_ASSERT(!this->file->children_attached);
|
||||||
|
|
||||||
|
DEBUG_SYNC(current_thd, "before_myisammrg_attach");
|
||||||
/* Must call this with children list in place. */
|
/* Must call this with children list in place. */
|
||||||
DBUG_ASSERT(this->table->pos_in_table_list->next_global == this->children_l);
|
DBUG_ASSERT(this->table->pos_in_table_list->next_global == this->children_l);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user