From ac3c60d5528f3abdd3a1eb9fade6c05c984fe844 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 4 Jan 2012 20:10:15 +0100 Subject: [PATCH 01/21] report innodb_file_per_table, innodb_flush_log_at_trx_commit, innodb_flush_method --- plugin/feedback/feedback.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index a8c7ee82ac2..e2daa052859 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -126,6 +126,7 @@ static LEX_STRING vars_filter[]= { {C_STRING_WITH_LEN("ft\\_m%")}, {C_STRING_WITH_LEN("have\\_%")}, {C_STRING_WITH_LEN("%\\_size")}, + {C_STRING_WITH_LEN("innodb_f%")}, {C_STRING_WITH_LEN("%\\_length%")}, {C_STRING_WITH_LEN("%\\_timeout")}, {C_STRING_WITH_LEN("large\\_%")}, From dacaaf22a3f132df5573fe8e58c0617c30c5e9fc Mon Sep 17 00:00:00 2001 From: Karen Langford Date: Wed, 11 Jan 2012 18:40:29 +0100 Subject: [PATCH 02/21] Fixes required to build on AIX --- cmd-line-utils/libedit/chartype.h | 6 +++--- cmd-line-utils/libedit/eln.c | 2 +- cmd-line-utils/libedit/readline.c | 2 +- unittest/mysys/bitmap-t.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmd-line-utils/libedit/chartype.h b/cmd-line-utils/libedit/chartype.h index 678d13683be..40012afb47d 100644 --- a/cmd-line-utils/libedit/chartype.h +++ b/cmd-line-utils/libedit/chartype.h @@ -45,11 +45,11 @@ * seems to actually advertise this properly, despite Unicode 3.1 having * been around since 2001... */ -/* XXXMYSQL : Added FreeBSD to bypass this check. - TODO : Verify if FreeBSD stores ISO 10646 in wchar_t. */ +/* XXXMYSQL : Added FreeBSD & AIX to bypass this check. + TODO : Verify if FreeBSD & AIX stores ISO 10646 in wchar_t. */ #if !defined(__NetBSD__) && !defined(__sun) \ && !(defined(__APPLE__) && defined(__MACH__)) \ - && !defined(__FreeBSD__) + && !defined(__FreeBSD__) && !defined(_AIX) #ifndef __STDC_ISO_10646__ /* In many places it is assumed that the first 127 code points are ASCII * compatible, so ensure wchar_t indeed does ISO 10646 and not some other diff --git a/cmd-line-utils/libedit/eln.c b/cmd-line-utils/libedit/eln.c index 4b9f16c38f3..f996367115a 100644 --- a/cmd-line-utils/libedit/eln.c +++ b/cmd-line-utils/libedit/eln.c @@ -200,7 +200,7 @@ el_set(EditLine *el, int op, ...) ret = -1; goto out; } - // XXX: The two strdup's leak + /* XXX: The two strdups leak. */ ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]), func); ct_free_argv(wargv); diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index eaf26d4c497..a2a92edc1b4 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1978,7 +1978,7 @@ rl_callback_read_char() } else wbuf = NULL; (*(void (*)(const char *))rl_linefunc)(wbuf); - //el_set(e, EL_UNBUFFERED, 1); + /*el_set(e, EL_UNBUFFERED, 1);*/ } } diff --git a/unittest/mysys/bitmap-t.c b/unittest/mysys/bitmap-t.c index 0127b7b86f4..9a5337c79b5 100644 --- a/unittest/mysys/bitmap-t.c +++ b/unittest/mysys/bitmap-t.c @@ -429,7 +429,7 @@ my_bool test_intersect(MY_BITMAP *map, uint bitsize) { uint bitsize2 = 1 + get_rand_bit(MAX_TESTED_BITMAP_SIZE - 1); MY_BITMAP map2; - uint32 map2buf[bitsize2]; + uint32 map2buf[MAX_TESTED_BITMAP_SIZE]; uint i, test_bit1, test_bit2, test_bit3; if (bitmap_init(&map2, map2buf, bitsize2, FALSE)) { From 8fedf8ac75dc64eea281df27baa064c00078580a Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 25 Jan 2012 11:34:43 +0100 Subject: [PATCH 03/21] mtr runs only "big" tests, if --big-test is repeated twice --- mysql-test/lib/mtr_cases.pm | 7 +++++++ mysql-test/mysql-test-run.pl | 5 +++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index 727e56ac77a..8b87ad367e3 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -925,6 +925,13 @@ sub collect_one_test_case { return $tinfo } + if ( ! $tinfo->{'big_test'} and $::opt_big_test > 1 ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Small test"; + return $tinfo + } + if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries ) { $tinfo->{'skip'}= 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index b2c7ee2fc37..cb6f7b4a486 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -986,7 +986,7 @@ sub command_line_setup { 'skip-test=s' => \&collect_option, 'do-test=s' => \&collect_option, 'start-from=s' => \&collect_option, - 'big-test' => \$opt_big_test, + 'big-test+' => \$opt_big_test, 'combination=s' => \@opt_combinations, 'skip-combinations' => \&collect_option, 'experimental=s' => \@opt_experimentals, @@ -5984,7 +5984,8 @@ Options to control what test suites or cases to run list of suite names. The default is: "$DEFAULT_SUITES" skip-rpl Skip the replication test cases. - big-test Also run tests marked as "big" + big-test Also run tests marked as "big". Repeat this option + twice to run only "big" tests. staging-run Run a limited number of tests (no slow tests). Used for running staging trees with valgrind. enable-disabled Run also tests marked as disabled From 607aab9c1d68a3b80bdb52a6c73fd6be1aa52764 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 16 Feb 2012 08:49:10 +0200 Subject: [PATCH 04/21] Counters for Index Condition Pushdown added (MDEV-130). --- mysql-test/include/icp_tests.inc | 22 ++++++++++++++++++++++ mysql-test/r/innodb_icp.result | 27 +++++++++++++++++++++++++++ mysql-test/r/join_cache.result | 17 +++++++++++++++++ mysql-test/r/maria_icp.result | 27 +++++++++++++++++++++++++++ mysql-test/r/myisam_icp.result | 27 +++++++++++++++++++++++++++ mysql-test/r/status.result | 6 +++++- mysql-test/r/status_user.result | 2 ++ mysql-test/t/join_cache.test | 5 +++++ sql/mysqld.cc | 2 ++ sql/sql_class.h | 2 ++ sql/sql_join_cache.cc | 22 ++++++++++++++++++++-- sql/sql_join_cache.h | 2 ++ storage/maria/ha_maria.cc | 8 +++++++- storage/myisam/ha_myisam.cc | 8 +++++++- storage/xtradb/handler/ha_innodb.cc | 8 +++++++- storage/xtradb/handler/ha_innodb.h | 2 ++ 16 files changed, 181 insertions(+), 6 deletions(-) diff --git a/mysql-test/include/icp_tests.inc b/mysql-test/include/icp_tests.inc index e77cb220375..f412843ded0 100644 --- a/mysql-test/include/icp_tests.inc +++ b/mysql-test/include/icp_tests.inc @@ -852,3 +852,25 @@ SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +--echo # check "Handler_pushed" status varuiables +CREATE TABLE t1 ( + c1 CHAR(1), + c2 CHAR(1), + KEY (c1) +); + +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); + +flush status; +show status like "Handler_pushed%"; + +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; + +show status like "Handler_pushed%"; + +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; + +show status like "Handler_pushed%"; + +DROP TABLE t1; + diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result index 08238289330..ccbae98d137 100644 --- a/mysql-test/r/innodb_icp.result +++ b/mysql-test/r/innodb_icp.result @@ -808,5 +808,32 @@ COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# check "Handler_pushed" status varuiables +CREATE TABLE t1 ( +c1 CHAR(1), +c2 CHAR(1), +KEY (c1) +); +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); +flush status; +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +DROP TABLE t1; set optimizer_switch=@innodb_icp_tmp; set storage_engine= @save_storage_engine; diff --git a/mysql-test/r/join_cache.result b/mysql-test/r/join_cache.result index dda0f4c8f66..6908f40e854 100644 --- a/mysql-test/r/join_cache.result +++ b/mysql-test/r/join_cache.result @@ -3506,6 +3506,7 @@ insert into t2 values (2,1, 'qwerty'),(2,2, 'qwerty'),(2,3, 'qwerty'), insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty'); insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'), (4,4, 'qwerty'); +flush status; set join_cache_level=5; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3519,6 +3520,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 20 +Handler_pushed_index_cond_filtered 16 set join_cache_level=6; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3532,6 +3537,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 40 +Handler_pushed_index_cond_filtered 32 set join_cache_level=7; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3545,6 +3554,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 60 +Handler_pushed_index_cond_filtered 48 set join_cache_level=8; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; @@ -3558,6 +3571,10 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where 1 SIMPLE t2 ref f1 f1 4 test.t1.f1 3 Using index condition(BKA); Using where; Using join buffer (flat, BKAH join); Key-ordered Rowid-ordered scan +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 80 +Handler_pushed_index_cond_filtered 64 drop table t1,t2; set join_cache_level=default; # diff --git a/mysql-test/r/maria_icp.result b/mysql-test/r/maria_icp.result index 2d2b4d0c1f7..b9d3ca6c7c0 100644 --- a/mysql-test/r/maria_icp.result +++ b/mysql-test/r/maria_icp.result @@ -814,5 +814,32 @@ COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# check "Handler_pushed" status varuiables +CREATE TABLE t1 ( +c1 CHAR(1), +c2 CHAR(1), +KEY (c1) +); +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); +flush status; +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +DROP TABLE t1; set storage_engine= @save_storage_engine; set optimizer_switch=@maria_icp_tmp; diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result index c480e35df42..3171753adb4 100644 --- a/mysql-test/r/myisam_icp.result +++ b/mysql-test/r/myisam_icp.result @@ -812,6 +812,33 @@ COUNT(*) 1478 SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2; +# check "Handler_pushed" status varuiables +CREATE TABLE t1 ( +c1 CHAR(1), +c2 CHAR(1), +KEY (c1) +); +INSERT INTO t1 VALUES ('3', '3'),('4','4'),('5','5'); +flush status; +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 +SELECT * FROM t1 FORCE INDEX(c1) WHERE (c1='3' or c1='4') and c1 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +SELECT * FROM t1 WHERE (c2='3' or c2='4') and c2 % 2 = 0 ; +c1 c2 +4 4 +show status like "Handler_pushed%"; +Variable_name Value +Handler_pushed_index_cond_checks 2 +Handler_pushed_index_cond_filtered 1 +DROP TABLE t1; drop table if exists t0, t1, t1i, t1m; # # BUG#826935 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed diff --git a/mysql-test/r/status.result b/mysql-test/r/status.result index b0744726390..e75cabe0e58 100644 --- a/mysql-test/r/status.result +++ b/mysql-test/r/status.result @@ -276,6 +276,8 @@ Handler_commit 0 Handler_delete 0 Handler_discover 0 Handler_prepare 0 +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 4 Handler_read_next 0 @@ -297,7 +299,7 @@ Created_tmp_files 0 Created_tmp_tables 2 Handler_tmp_update 2 Handler_tmp_write 7 -Rows_tmp_read 35 +Rows_tmp_read 37 drop table t1; CREATE TABLE t1 (i int(11) DEFAULT NULL, KEY i (i) ) ENGINE=MyISAM; insert into t1 values (1),(2),(3),(4),(5); @@ -311,6 +313,8 @@ Handler_commit 0 Handler_delete 0 Handler_discover 0 Handler_prepare 0 +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 2 Handler_read_next 2 diff --git a/mysql-test/r/status_user.result b/mysql-test/r/status_user.result index 17c44df1d3c..175839b2098 100644 --- a/mysql-test/r/status_user.result +++ b/mysql-test/r/status_user.result @@ -101,6 +101,8 @@ Handler_commit 19 Handler_delete 1 Handler_discover 0 Handler_prepare 18 +Handler_pushed_index_cond_checks 0 +Handler_pushed_index_cond_filtered 0 Handler_read_first 0 Handler_read_key 3 Handler_read_next 0 diff --git a/mysql-test/t/join_cache.test b/mysql-test/t/join_cache.test index 9d7b07f6b9e..6cb8f48bd70 100644 --- a/mysql-test/t/join_cache.test +++ b/mysql-test/t/join_cache.test @@ -1526,12 +1526,14 @@ insert into t2 values (3,1, 'qwerty'),(3,4, 'qwerty'); insert into t2 values (4,1, 'qwerty'),(4,2, 'qwerty'),(4,3, 'qwerty'), (4,4, 'qwerty'); +flush status; set join_cache_level=5; select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; set join_cache_level=6; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1539,6 +1541,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; set join_cache_level=7; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1546,6 +1549,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; set join_cache_level=8; select t2.f1, t2.f2, t2.f3 from t1,t2 @@ -1553,6 +1557,7 @@ where t1.f1=t2.f1 and t2.f2 between t1.f1 and t1.f2 and t2.f2 + 1 >= t1.f1 + 1; explain select t2.f1, t2.f2, t2.f3 from t1,t2 where t1.f1=t2.f1 and t2.f2 between t1.f1 and t2.f2; +show status like "Handler_pushed%"; drop table t1,t2; set join_cache_level=default; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 109d0220a4a..4e2fa473b8d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -8291,6 +8291,8 @@ SHOW_VAR status_vars[]= { {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_multi_range_read_init_count), SHOW_LONG_STATUS}, #endif {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, + {"Handler_pushed_index_cond_checks",(char*) offsetof(STATUS_VAR, ha_pushed_index_cond_checks), SHOW_LONG_STATUS}, + {"Handler_pushed_index_cond_filtered",(char*) offsetof(STATUS_VAR, ha_pushed_index_cond_filtered), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 58af7888385..c04af55a127 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -588,6 +588,8 @@ typedef struct system_status_var ulong ha_tmp_update_count; ulong ha_tmp_write_count; ulong ha_prepare_count; + ulong ha_pushed_index_cond_checks; + ulong ha_pushed_index_cond_filtered; ulong ha_discover_count; ulong ha_savepoint_count; ulong ha_savepoint_rollback_count; diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc index 78f95a7ac7e..15b5efbfacb 100644 --- a/sql/sql_join_cache.cc +++ b/sql/sql_join_cache.cc @@ -2576,6 +2576,15 @@ void JOIN_CACHE::print_explain_comment(String *str) str->append(STRING_WITH_LEN(")")); } +/** + get thread handle. +*/ + +THD *JOIN_CACHE::thd() +{ + return join->thd; +} + static void add_mrr_explain_info(String *str, uint mrr_mode, handler *file) { @@ -4015,7 +4024,11 @@ bool bka_skip_index_tuple(range_seq_t rseq, range_id_t range_info) { DBUG_ENTER("bka_skip_index_tuple"); JOIN_CACHE_BKA *cache= (JOIN_CACHE_BKA *) rseq; - bool res= cache->skip_index_tuple(range_info); + THD *thd= cache->thd(); + bool res; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= cache->skip_index_tuple(range_info))) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); DBUG_RETURN(res); } @@ -4490,7 +4503,12 @@ bool bkah_skip_index_tuple(range_seq_t rseq, range_id_t range_info) { DBUG_ENTER("bka_unique_skip_index_tuple"); JOIN_CACHE_BKAH *cache= (JOIN_CACHE_BKAH *) rseq; - DBUG_RETURN(cache->skip_index_tuple(range_info)); + THD *thd= cache->thd(); + bool res; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= cache->skip_index_tuple(range_info))) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + DBUG_RETURN(res); } diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h index f5d64d5530a..ba8e4ba8e4a 100644 --- a/sql/sql_join_cache.h +++ b/sql/sql_join_cache.h @@ -643,6 +643,8 @@ public: /* Add a comment on the join algorithm employed by the join cache */ virtual void print_explain_comment(String *str); + THD *thd(); + virtual ~JOIN_CACHE() {} void reset_join(JOIN *j) { join= j; } void free() diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 92b2a965706..bee7888eb5d 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2248,12 +2248,18 @@ C_MODE_START ICP_RESULT index_cond_func_maria(void *arg) { ha_maria *h= (ha_maria*)arg; + THD *thd= ((TABLE*) h->file->external_ref)->in_use; + ICP_RESULT res; if (h->end_range) { if (h->compare_key2(h->end_range) > 0) return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ } - return h->pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= h->pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH) == + ICP_NO_MATCH) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + return res; } C_MODE_END diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 5f1caa31b74..1f6e1fd6838 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1770,12 +1770,18 @@ C_MODE_START ICP_RESULT index_cond_func_myisam(void *arg) { ha_myisam *h= (ha_myisam*)arg; + THD *thd= ((TABLE*) h->file->external_ref)->in_use; + ICP_RESULT res; if (h->end_range) { if (h->compare_key2(h->end_range) > 0) return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ } - return (ICP_RESULT) test(h->pushed_idx_cond->val_int()); + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= (ICP_RESULT) test(h->pushed_idx_cond->val_int())) == + ICP_NO_MATCH) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + return res; } C_MODE_END diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 972a4407eea..9db7e9a715b 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -12583,6 +12583,8 @@ innobase_index_cond( void* file) /*!< in/out: pointer to ha_innobase */ { ha_innobase *h= (ha_innobase*) file; + THD *thd= h->thd(); + enum icp_result res; if (h->is_thd_killed()) return ICP_ABORTED_BY_USER; @@ -12592,7 +12594,11 @@ innobase_index_cond( if (h->compare_key2(h->end_range) > 0) return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ } - return h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH; + status_var_increment(thd->status_var.ha_pushed_index_cond_checks); + if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == + ICP_NO_MATCH) + status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); + return res; } /** Attempt to push down an index condition. diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 749438e0c89..6ec036eb8cc 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -223,6 +223,8 @@ class ha_innobase: public handler bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); bool check_if_supported_virtual_columns(void) { return TRUE; } + + THD *thd() { return user_thd; } private: /** Builds a 'template' to the prebuilt struct. From e98e05da7a0f817849529dfaf89e9b8010b16f4e Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 16 Feb 2012 18:56:10 +0400 Subject: [PATCH 05/21] Added comments --- sql/sql_list.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/sql_list.h b/sql/sql_list.h index 873a8656ebe..adedd9a3a4d 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -257,7 +257,12 @@ public: last= &first; return tmp->info; } - inline void disjoin(base_list *list) + /* + Remove from this list elements that are contained in the passed list. + We assume that the passed list is a tail of this list (that is, the whole + list_node* elements are shared). + */ + inline void disjoin(const base_list *list) { list_node **prev= &first; list_node *node= first; From 541334c5ac11efae4918116b152d9085bd82caee Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Thu, 16 Feb 2012 20:15:57 +0400 Subject: [PATCH 06/21] Backport of: timestamp: Thu 2011-12-01 15:12:10 +0100 Fix for Bug#13430436 PERFORMANCE DEGRADATION IN SYSBENCH ON INNODB DUE TO ICP When running sysbench on InnoDB there is a performance degradation due to index condition pushdown (ICP). Several of the queries in sysbench have a WHERE condition that the optimizer uses for executing these queries as range scans. The upper and lower limit of the range scan will ensure that the WHERE condition is fulfilled. Still, the WHERE condition is part of the queries' condition and if ICP is enabled the condition will be pushed down to InnoDB as an index condition. Due to the range scan's upper and lower limits ensure that the WHERE condition is fulfilled, the pushed index condition will not filter out any records. As a result the use of ICP for these queries results in a performance overhead for sysbench. This overhead comes from using resources for determining the part of the condition that can be pushed down to InnoDB and overhead in InnoDB for executing the pushed index condition. With the default configuration for sysbench the range scans will use the primary key. This is a clustered index in InnoDB. Using ICP on a clustered index provides the lowest performance benefit since the entire record is part of the clustered index and in InnoDB it has the highest relative overhead for executing the pushed index condition. The fix for removing the overhead ICP introduces when running sysbench is to disable use of ICP when the index used by the query is a clustered index. When WL#6061 is implemented this change should be re-evaluated. --- mysql-test/r/index_merge_innodb.result | 2 +- mysql-test/r/innodb.result | 2 +- mysql-test/r/innodb_icp.result | 14 +++++----- mysql-test/r/innodb_mrr_cpk.result | 6 ++-- .../r/range_vs_index_merge_innodb.result | 28 +++++++++---------- mysql-test/suite/innodb/r/innodb.result | 2 +- .../r/innodb_lock_wait_timeout_1.result | 4 +-- mysql-test/suite/innodb/r/innodb_mysql.result | 2 +- .../suite/vcol/r/vcol_select_innodb.result | 6 ++-- sql/opt_index_cond_pushdown.cc | 14 ++++++++-- 10 files changed, 45 insertions(+), 35 deletions(-) diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result index 0f9da2ea3b6..50b0147b6ad 100644 --- a/mysql-test/r/index_merge_innodb.result +++ b/mysql-test/r/index_merge_innodb.result @@ -549,7 +549,7 @@ primary key (pk1, pk2) ); explain select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 9 Using index condition; Using where +1 SIMPLE t1 range PRIMARY,key1 PRIMARY 8 NULL 9 Using where select * from t1 where pk1 = 1 and pk2 < 80 and key1=0; pk1 pk2 key1 key2 pktail1ok pktail2ok pktail3bad pktail4bad pktail5bad pk2copy badkey filler1 filler2 1 10 0 0 0 0 0 0 0 10 0 filler-data-10 filler2 diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 3b69791d373..9ab7ed4eec7 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -783,7 +783,7 @@ create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); explain select * from t1 where a > 0 and a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using where drop table t1; create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb; insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL'); diff --git a/mysql-test/r/innodb_icp.result b/mysql-test/r/innodb_icp.result index ccbae98d137..d8e41113f63 100644 --- a/mysql-test/r/innodb_icp.result +++ b/mysql-test/r/innodb_icp.result @@ -167,7 +167,7 @@ WHERE ts BETWEEN '0000-00-00' AND '2010-00-01 00:00:00' ORDER BY ts DESC LIMIT 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where DROP TABLE t1; # @@ -431,7 +431,7 @@ SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Using where -2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using index condition +2 DEPENDENT SUBQUERY it eq_ref PRIMARY PRIMARY 4 func 1 Using where 2 DEPENDENT SUBQUERY t2 index NULL PRIMARY 4 NULL 3 Using where; Using index; Using join buffer (flat, BNL join) SELECT * FROM t1 WHERE pk IN (SELECT it.pk FROM t2 JOIN t2 AS it ON it.i=it.i WHERE it.pk-t1.i<10); @@ -452,7 +452,7 @@ PRIMARY KEY (pk) INSERT INTO t1 VALUES (1,9),(2,7),(3,6),(4,3),(5,1); EXPLAIN SELECT pk, c1 FROM t1 WHERE pk <> 3; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where SET SESSION optimizer_switch='index_condition_pushdown=off'; SELECT pk, c1 FROM t1 WHERE pk <> 3; pk c1 @@ -507,8 +507,8 @@ SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1 WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using index condition; Using where -1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using join buffer (flat, BNL join) +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where +1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using join buffer (flat, BNL join) SELECT c2 FROM t1 JOIN t2 ON t1.c1 = t2.c1 WHERE (t2.pk <= 4 AND t1.pk IN (2,1)) OR (t1.pk > 1 AND t2.pk BETWEEN 6 AND 6); @@ -680,7 +680,7 @@ EXPLAIN SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using where; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort 1 SIMPLE t2 ref a a 515 test.t1.a 1 Using where SELECT t1.b, t1.c FROM t1, t2 WHERE t1.a = t2.a AND t1.b != 0 HAVING t1.c != 5 ORDER BY t1.c; @@ -793,7 +793,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t ALL PRIMARY,c NULL NULL NULL 64 Using where 1 PRIMARY t2 ref g g 5 test.t.c 9 Using where 2 DEPENDENT SUBQUERY t1 index PRIMARY d 3 NULL 64 Using where; Using index -2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using index condition; Using where +2 DEPENDENT SUBQUERY t2 eq_ref PRIMARY PRIMARY 4 test.t1.a 1 Using where SELECT COUNT(*) FROM t1 AS t, t2 WHERE c = g AND (EXISTS (SELECT * FROM t1, t2 WHERE a = f AND h <= t.e AND a > t.b) diff --git a/mysql-test/r/innodb_mrr_cpk.result b/mysql-test/r/innodb_mrr_cpk.result index 81536f2a43b..90f59b96e61 100644 --- a/mysql-test/r/innodb_mrr_cpk.result +++ b/mysql-test/r/innodb_mrr_cpk.result @@ -82,7 +82,7 @@ insert into t2 values ('a-1010=A', 1010), ('a-1030=A', 1030), ('a-1020=A', 1020) explain select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t1 eq_ref PRIMARY PRIMARY 30 test.t2.a,test.t2.b 1 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered scan +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 30 test.t2.a,test.t2.b 1 Using where; Using join buffer (flat, BKA join); Key-ordered scan select * from t1, t2 where t1.a=t2.a and t1.b=t2.b; a b filler a b a-1010=A 1010 filler a-1010=A 1010 @@ -91,7 +91,7 @@ a-1030=A 1030 filler a-1030=A 1030 explain select * from t1, t2 where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t1 ref PRIMARY PRIMARY 26 test.t2.a 1 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered scan +1 SIMPLE t1 ref PRIMARY PRIMARY 26 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered scan select * from t1, t2 where t1.a=t2.a; a b filler a b a-1010=A 1010 filler a-1010=A 1010 @@ -133,7 +133,7 @@ set join_cache_level=6; explain select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where -1 SIMPLE t1 ref PRIMARY PRIMARY 4 test.t2.a 1 Using index condition(BKA); Using join buffer (flat, BKA join); Key-ordered scan +1 SIMPLE t1 ref PRIMARY PRIMARY 4 test.t2.a 1 Using where; Using join buffer (flat, BKA join); Key-ordered scan select * from t1, t2 where t1.a=t2.a and t2.b + t1.b > 100; a b c filler a b set optimizer_switch='index_condition_pushdown=off'; diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result index 57862ded4f2..c42f80f0e85 100644 --- a/mysql-test/r/range_vs_index_merge_innodb.result +++ b/mysql-test/r/range_vs_index_merge_innodb.result @@ -328,15 +328,15 @@ ID Name Country Population EXPLAIN SELECT * FROM City WHERE (ID < 10) OR (ID BETWEEN 100 AND 110); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 20 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 20 Using where EXPLAIN SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 100 AND 200); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 200 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 200 Using where EXPLAIN SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1500); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 1198 Using index condition; Using where +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 1198 Using where EXPLAIN SELECT * FROM City WHERE Country > 'A' AND Country < 'ARG'; id select_type table type possible_keys key key_len ref rows Extra @@ -355,7 +355,7 @@ WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND (Name LIKE 'P%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 20 Using index condition; Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 20 Using where EXPLAIN SELECT * FROM City WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) @@ -369,7 +369,7 @@ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 200) AND (Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000))); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using index condition; Using where +1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using where SELECT * FROM City USE INDEX () WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG'))) OR ((ID BETWEEN 100 AND 110) AND @@ -601,11 +601,11 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3400 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 400 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 400 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE Name LIKE 'P%'; id select_type table type possible_keys key key_len ref rows Extra @@ -765,27 +765,27 @@ id select_type table type possible_keys key key_len ref rows Extra EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3790 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 4025 AND 4035; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 4028 AND 4032; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 5 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3500 AND 3800; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 300 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 300 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 4000 AND 4300; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 80 Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 250 and 260 ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using index condition +1 SIMPLE City range PRIMARY PRIMARY 4 NULL 11 Using where EXPLAIN SELECT * FROM City WHERE (Population > 101000 AND Population < 102000); id select_type table type possible_keys key key_len ref rows Extra @@ -1422,7 +1422,7 @@ SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using index condition; Using where +1 SIMPLE t1 range PRIMARY,idx PRIMARY 4 NULL 1 Using where SELECT * FROM t1 WHERE t1.a>300 AND t1.c!=0 AND t1.b>=350 AND t1.b<=400 AND (t1.c=0 OR t1.a=500); diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index e98d3931020..80ff21230fb 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -778,7 +778,7 @@ create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); explain select * from t1 where a > 0 and a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using index condition +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using where drop table t1; create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) engine=innodb; insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL'); diff --git a/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result index 30e58aacff5..2cb761c6ea1 100644 --- a/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result +++ b/mysql-test/suite/innodb/r/innodb_lock_wait_timeout_1.result @@ -121,7 +121,7 @@ key PRIMARY key_len 4 ref t2.a rows 1 -Extra Using index condition; Using where +Extra Using where id 2 select_type DERIVED table NULL @@ -328,7 +328,7 @@ key PRIMARY key_len 4 ref t2.a rows 1 -Extra Using index condition; Using where +Extra Using where id 2 select_type DERIVED table NULL diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 4dcce4d0373..62dbc849241 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2839,7 +2839,7 @@ SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.pk = t2.a WHERE t1.pk >= 6 HAVING t1.a<> 0 AND t1.a <> 11 ORDER BY t1.a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using index condition; Using filesort +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 4 Using where; Using filesort 1 SIMPLE t2 ref a a 5 test.t1.pk 1 Using index SELECT t1.a FROM t1 LEFT JOIN t2 ON t1.pk = t2.a WHERE t1.pk >= 6 HAVING t1.a<> 0 AND t1.a <> 11 diff --git a/mysql-test/suite/vcol/r/vcol_select_innodb.result b/mysql-test/suite/vcol/r/vcol_select_innodb.result index be84fa74c2e..14cf325feb1 100644 --- a/mysql-test/suite/vcol/r/vcol_select_innodb.result +++ b/mysql-test/suite/vcol/r/vcol_select_innodb.result @@ -152,7 +152,7 @@ a b c 2 -2 -2 explain select * from t3 where a between 1 and 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using index condition +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where # SELECT * FROM tbl_name WHERE select * from t3 where b between -2 and -1; a b c @@ -176,7 +176,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using filesort +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort # SELECT * FROM tbl_name WHERE ORDER BY select * from t3 where a between 1 and 2 order by c; a b c @@ -184,7 +184,7 @@ a b c 1 -1 -1 explain select * from t3 where a between 1 and 2 order by c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using index condition; Using filesort +1 SIMPLE t3 range PRIMARY PRIMARY 4 NULL 2 Using where; Using filesort # SELECT * FROM tbl_name WHERE ORDER BY select * from t3 where b between -2 and -1 order by a; a b c diff --git a/sql/opt_index_cond_pushdown.cc b/sql/opt_index_cond_pushdown.cc index 5240267b4ac..c2b49d863a1 100644 --- a/sql/opt_index_cond_pushdown.cc +++ b/sql/opt_index_cond_pushdown.cc @@ -329,13 +329,23 @@ void push_index_cond(JOIN_TAB *tab, uint keyno) { DBUG_ENTER("push_index_cond"); Item *idx_cond; - + + /* + Backported the following from MySQL 5.6: + 6. The index is not a clustered index. The performance improvement + of pushing an index condition on a clustered key is much lower + than on a non-clustered key. This restriction should be + re-evaluated when WL#6061 is implemented. + */ if ((tab->table->file->index_flags(keyno, 0, 1) & HA_DO_INDEX_COND_PUSHDOWN) && optimizer_flag(tab->join->thd, OPTIMIZER_SWITCH_INDEX_COND_PUSHDOWN) && tab->join->thd->lex->sql_command != SQLCOM_UPDATE_MULTI && tab->join->thd->lex->sql_command != SQLCOM_DELETE_MULTI && - tab->type != JT_CONST && tab->type != JT_SYSTEM) + tab->type != JT_CONST && tab->type != JT_SYSTEM && + !(keyno == tab->table->s->primary_key && // (6) + tab->table->file->primary_key_is_clustered())) // (6) + { DBUG_EXECUTE("where", print_where(tab->select_cond, "full cond", QT_ORDINARY);); From c563ea0717f3de43b7331dd4368e9f9cf4559be0 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 16 Feb 2012 16:06:49 -0800 Subject: [PATCH 07/21] Fixed LP bug #933117. The bug was fixed with the code back-ported from the patch for LP bug 800184 pushed into mariadb-5.3. --- mysql-test/r/range.result | 15 +++++++++++++++ mysql-test/t/range.test | 14 ++++++++++++++ sql/opt_range.cc | 9 +++++++-- 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index ae63edf87b9..13ae77c13e3 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -1768,3 +1768,18 @@ SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; pk i4 pk i4 DROP TABLE t1; End of 5.1 tests +# +# LP Bug #533117: Wrong use_count in SEL_ARG trees +# (Bug #58731) +# +create table t1 (a int, b int, c int, key idx (a,b,c)); +insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1); +explain +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx idx 5 NULL 3 Using where; Using index +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +a b c +2 2 0 +2 2 1 +drop table t1; diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 6c9320b708a..a5ab6905b74 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1393,3 +1393,17 @@ SELECT * FROM t1, t1 as t2 WHERE t1.i4 BETWEEN t2.pk AND t2.pk; DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # LP Bug #533117: Wrong use_count in SEL_ARG trees +--echo # (Bug #58731) +--echo # + +create table t1 (a int, b int, c int, key idx (a,b,c)); +insert into t1 values (0,0,0), (2,2,0), (1,1,1), (2,2,1); + +explain +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; +select * from t1 force index (idx) where a >=1 and c <= 1 and a=b and b > 1; + +drop table t1; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index bc434e2edc1..185f3eecd3c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -498,6 +498,11 @@ public: pos->increment_use_count(count); } } + void incr_refs() + { + increment_use_count(1); + use_count++; + } void free_tree() { for (SEL_ARG *pos=first(); pos ; pos=pos->next) @@ -6475,8 +6480,8 @@ key_and(RANGE_OPT_PARAM *param, SEL_ARG *key1, SEL_ARG *key2, uint clone_flag) continue; SEL_ARG *next=key_and(param, e1->next_key_part, e2->next_key_part, clone_flag); - e1->increment_use_count(1); - e2->increment_use_count(1); + e1->incr_refs(); + e2->incr_refs(); if (!next || next->type != SEL_ARG::IMPOSSIBLE) { SEL_ARG *new_arg= e1->clone_and(e2); From 2d19b077d5816dcd3a8c84bb682cf2d83fa055f5 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 16 Feb 2012 20:13:28 -0800 Subject: [PATCH 08/21] Fixed LP bug #928352. This bug led to wrong values of the use_count fields in some SEL_ARG trees that triggered complains on the server side when executing the test case for LP bug 800184 if a debug build of the server was used. This was the result of the incomplete fix for bug 800184. To complete it the following corrections had to be made: - the copy constructor for SEL_TREE must call the new function incr_refs_all() instead of the function incr_refs(), because references to next key parts from any SEL_ARG tree belonging to the list of the first key part has to be adjusted. - the method and_sel_tree of the class SEL_IMERGE must use the copy constructor of the SEL_TREE class to make a copy of its second argument before it ANDs it with any SEL_TREE tree from the processed SEL_IMERGE object. --- sql/opt_range.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 8d4b2e971ad..e0841d3a696 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -552,6 +552,14 @@ public: increment_use_count(1); use_count++; } + void incr_refs_all() + { + for (SEL_ARG *pos=first(); pos ; pos=pos->next) + { + pos->increment_use_count(1); + } + use_count++; + } void free_tree() { for (SEL_ARG *pos=first(); pos ; pos=pos->next) @@ -1090,9 +1098,11 @@ int SEL_IMERGE::and_sel_tree(RANGE_OPT_PARAM *param, SEL_TREE *tree, for (SEL_TREE** or_tree= trees; or_tree != trees_next; or_tree++) { SEL_TREE *res_or_tree= 0; - if (!(res_or_tree= new SEL_TREE())) + SEL_TREE *and_tree= 0; + if (!(res_or_tree= new SEL_TREE()) || + !(and_tree= new SEL_TREE(tree, TRUE, param))) return (-1); - if (!and_range_trees(param, *or_tree, tree, res_or_tree)) + if (!and_range_trees(param, *or_tree, and_tree, res_or_tree)) { if (new_imerge->or_sel_tree(param, res_or_tree)) return (-1); @@ -1305,7 +1315,7 @@ SEL_TREE::SEL_TREE(SEL_TREE *arg, bool without_merges, for (uint idx= 0; idx < param->keys; idx++) { if ((keys[idx]= arg->keys[idx])) - keys[idx]->incr_refs(); + keys[idx]->incr_refs_all(); } if (without_merges) From bbb3527635627a404ab4a16be7598339e8e41139 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 17 Feb 2012 13:27:41 +0100 Subject: [PATCH 09/21] Remove engine-specific (but identical) icp callbacks. create one reusable common icp callback in the handler.cc. It can also increment status counters, without making the engine dependent on the exact THD layout (that is different in embedded). --- sql/handler.cc | 21 +++++++++++++++++++ sql/handler.h | 4 ++++ storage/maria/ha_maria.cc | 27 +++---------------------- storage/myisam/ha_myisam.cc | 28 +++----------------------- storage/xtradb/handler/ha_innodb.cc | 28 -------------------------- storage/xtradb/handler/ha_innodb.h | 1 - storage/xtradb/include/ha_prototypes.h | 2 +- storage/xtradb/row/row0sel.c | 2 +- 8 files changed, 33 insertions(+), 80 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index e165a16b544..4a8cd77ebc3 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -4555,6 +4555,27 @@ int handler::compare_key2(key_range *range) } +/** + ICP callback - to be called by an engine to check the pushed condition +*/ +extern "C" enum icp_result handler_index_cond_check(void* h_arg) +{ + handler *h= (handler*)h_arg; + THD *thd= h->table->in_use; + enum icp_result res; + + if (thd_killed(thd)) + return ICP_ABORTED_BY_USER; + + if (h->end_range && h->compare_key2(h->end_range) > 0) + return ICP_OUT_OF_RANGE; + h->increment_statistics(&SSV::ha_pushed_index_cond_checks); + if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == + ICP_NO_MATCH) + h->increment_statistics(&SSV::ha_pushed_index_cond_filtered); + return res; +} + int handler::index_read_idx_map(uchar * buf, uint index, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) diff --git a/sql/handler.h b/sql/handler.h index 87ac1ab9ef3..28d8a96a895 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1553,6 +1553,8 @@ public: {} }; +extern "C" enum icp_result handler_index_cond_check(void* h_arg); + uint calculate_key_len(TABLE *, uint, const uchar *, key_part_map); /* bitmap with first N+1 bits set @@ -2632,6 +2634,8 @@ public: { return ht; } inline int ha_write_tmp_row(uchar *buf); inline int ha_update_tmp_row(const uchar * old_data, uchar * new_data); + + friend enum icp_result handler_index_cond_check(void* h_arg); }; #include "multi_range_read.h" diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index bee7888eb5d..407350900bf 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2243,27 +2243,6 @@ int ha_maria::delete_row(const uchar * buf) return maria_delete(file, buf); } -C_MODE_START - -ICP_RESULT index_cond_func_maria(void *arg) -{ - ha_maria *h= (ha_maria*)arg; - THD *thd= ((TABLE*) h->file->external_ref)->in_use; - ICP_RESULT res; - if (h->end_range) - { - if (h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ - } - status_var_increment(thd->status_var.ha_pushed_index_cond_checks); - if ((res= h->pushed_idx_cond->val_int() ? ICP_MATCH : ICP_NO_MATCH) == - ICP_NO_MATCH) - status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); - return res; -} - -C_MODE_END - int ha_maria::index_read_map(uchar * buf, const uchar * key, key_part_map keypart_map, enum ha_rkey_function find_flag) @@ -2283,7 +2262,7 @@ int ha_maria::index_read_idx_map(uchar * buf, uint index, const uchar * key, /* Use the pushed index condition if it matches the index we're scanning */ end_range= NULL; if (index == pushed_idx_cond_keyno) - ma_set_index_cond_func(file, index_cond_func_maria, this); + ma_set_index_cond_func(file, handler_index_cond_check, this); error= maria_rkey(file, buf, index, key, keypart_map, find_flag); @@ -2364,7 +2343,7 @@ int ha_maria::index_init(uint idx, bool sorted) { active_index=idx; if (pushed_idx_cond_keyno == idx) - ma_set_index_cond_func(file, index_cond_func_maria, this); + ma_set_index_cond_func(file, handler_index_cond_check, this); return 0; } @@ -3797,7 +3776,7 @@ Item *ha_maria::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) pushed_idx_cond= idx_cond_arg; in_range_check_pushed_down= TRUE; if (active_index == pushed_idx_cond_keyno) - ma_set_index_cond_func(file, index_cond_func_maria, this); + ma_set_index_cond_func(file, handler_index_cond_check, this); return NULL; } diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 1f6e1fd6838..a6ece45734a 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1765,33 +1765,11 @@ int ha_myisam::delete_row(const uchar *buf) } -C_MODE_START - -ICP_RESULT index_cond_func_myisam(void *arg) -{ - ha_myisam *h= (ha_myisam*)arg; - THD *thd= ((TABLE*) h->file->external_ref)->in_use; - ICP_RESULT res; - if (h->end_range) - { - if (h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ - } - status_var_increment(thd->status_var.ha_pushed_index_cond_checks); - if ((res= (ICP_RESULT) test(h->pushed_idx_cond->val_int())) == - ICP_NO_MATCH) - status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); - return res; -} - -C_MODE_END - - int ha_myisam::index_init(uint idx, bool sorted) { active_index=idx; if (pushed_idx_cond_keyno == idx) - mi_set_index_cond_func(file, index_cond_func_myisam, this); + mi_set_index_cond_func(file, handler_index_cond_check, this); return 0; } @@ -1827,7 +1805,7 @@ int ha_myisam::index_read_idx_map(uchar *buf, uint index, const uchar *key, /* Use the pushed index condition if it matches the index we're scanning */ end_range= NULL; if (index == pushed_idx_cond_keyno) - mi_set_index_cond_func(file, index_cond_func_myisam, this); + mi_set_index_cond_func(file, handler_index_cond_check, this); res= mi_rkey(file, buf, index, key, keypart_map, find_flag); mi_set_index_cond_func(file, NULL, 0); return res; @@ -2346,7 +2324,7 @@ Item *ha_myisam::idx_cond_push(uint keyno_arg, Item* idx_cond_arg) pushed_idx_cond= idx_cond_arg; in_range_check_pushed_down= TRUE; if (active_index == pushed_idx_cond_keyno) - mi_set_index_cond_func(file, index_cond_func_myisam, this); + mi_set_index_cond_func(file, handler_index_cond_check, this); return NULL; } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 9db7e9a715b..0d64a3f8b14 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -12573,34 +12573,6 @@ bool ha_innobase::is_thd_killed() * Index Condition Pushdown interface implementation */ -/*************************************************************//** -InnoDB index push-down condition check -@return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ -extern "C" UNIV_INTERN -enum icp_result -innobase_index_cond( -/*================*/ - void* file) /*!< in/out: pointer to ha_innobase */ -{ - ha_innobase *h= (ha_innobase*) file; - THD *thd= h->thd(); - enum icp_result res; - - if (h->is_thd_killed()) - return ICP_ABORTED_BY_USER; - - if (h->end_range) - { - if (h->compare_key2(h->end_range) > 0) - return ICP_OUT_OF_RANGE; /* caller should return HA_ERR_END_OF_FILE already */ - } - status_var_increment(thd->status_var.ha_pushed_index_cond_checks); - if ((res= h->pushed_idx_cond->val_int()? ICP_MATCH : ICP_NO_MATCH) == - ICP_NO_MATCH) - status_var_increment(thd->status_var.ha_pushed_index_cond_filtered); - return res; -} - /** Attempt to push down an index condition. * @param[in] keyno MySQL key number * @param[in] idx_cond Index condition to be checked diff --git a/storage/xtradb/handler/ha_innodb.h b/storage/xtradb/handler/ha_innodb.h index 6ec036eb8cc..d234a7236e3 100644 --- a/storage/xtradb/handler/ha_innodb.h +++ b/storage/xtradb/handler/ha_innodb.h @@ -224,7 +224,6 @@ class ha_innobase: public handler uint table_changes); bool check_if_supported_virtual_columns(void) { return TRUE; } - THD *thd() { return user_thd; } private: /** Builds a 'template' to the prebuilt struct. diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h index db71c37afc3..28c28838400 100644 --- a/storage/xtradb/include/ha_prototypes.h +++ b/storage/xtradb/include/ha_prototypes.h @@ -252,7 +252,7 @@ InnoDB index push-down condition check @return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ UNIV_INTERN enum icp_result -innobase_index_cond( +handler_index_cond_check( /*================*/ void* file) /*!< in/out: pointer to ha_innobase */ __attribute__((nonnull, warn_unused_result)); diff --git a/storage/xtradb/row/row0sel.c b/storage/xtradb/row/row0sel.c index fca3c90109f..52a6263efe5 100644 --- a/storage/xtradb/row/row0sel.c +++ b/storage/xtradb/row/row0sel.c @@ -3443,7 +3443,7 @@ row_search_idx_cond_check( index, if the case of the column has been updated in the past, or a record has been deleted and a record inserted in a different case. */ - result = innobase_index_cond(prebuilt->idx_cond); + result = handler_index_cond_check(prebuilt->idx_cond); switch (result) { case ICP_MATCH: /* Convert the remaining fields to MySQL format. From cd81f5783071d76d14a7aeb804e874345b1f3254 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 18 Feb 2012 16:06:38 -0800 Subject: [PATCH 10/21] Fixed LP bug #934342. An outer join query with a semi-join subquery could return a wrong result if the optimizer chose to materialize the subquery. It happened because when substituting for the best field into a ref item used to build access keys not all COND_EQUAL objects that could be employed at substitution were checked. Also refined some code in the function check_join_cache_usage to make it safer. --- mysql-test/r/subselect_sj_jcl6.result | 80 +++++++++++++++++++++++++++ mysql-test/t/subselect_sj_jcl6.test | 54 ++++++++++++++++++ sql/sql_select.cc | 21 +++++-- 3 files changed, 150 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index dd358ced14a..4ac15ea654f 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2753,6 +2753,86 @@ DROP table t1, t2; set @@optimizer_switch= @os_912513; set @@join_cache_level= @jcl_912513; # End +# +# BUG#934342: outer join + semijoin materialization +# + join_cache_level > 2 +# +CREATE TABLE t1 (a varchar(1), b varchar(1), INDEX idx_a(a) ); +INSERT INTO t1 VALUES ('v','v'), ('w','w'), ('t','t'); +CREATE TABLE t2 (c varchar(1), INDEX idx_c(c) ); +INSERT INTO t2 VALUES ('v'), ('v'), ('s'), ('j'); +CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) ); +INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j'); +INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m'); +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; +set join_cache_level=0; +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c +v v v +v v v +w w NULL +t t NULL +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c d +v v v v +v v v v +w w NULL NULL +t t NULL NULL +set join_cache_level=6; +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t2 ref idx_c idx_c 4 test.t1.b 2 Using where; Using index +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c +v v v +v v v +w w NULL +t t NULL +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL idx_a NULL NULL NULL 3 +1 PRIMARY eq_ref distinct_key distinct_key 10 func,func 1 +1 PRIMARY t3 ref idx_c idx_c 4 test.t1.b 2 Using where; Using join buffer (flat, BKA join); Key-ordered Rowid-ordered scan +2 MATERIALIZED t ALL idx_a NULL NULL NULL 3 +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) +WHERE (a, b) IN (SELECT a, b FROM t1 t); +a b c d +v v v v +v v v v +w w NULL NULL +t t NULL NULL +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; +DROP TABLE t1,t2,t3; +# End set join_cache_level=default; show variables like 'join_cache_level'; Variable_name Value diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test index 6d563cab3d3..9fe60cdd3d9 100644 --- a/mysql-test/t/subselect_sj_jcl6.test +++ b/mysql-test/t/subselect_sj_jcl6.test @@ -116,6 +116,60 @@ set @@join_cache_level= @jcl_912513; --echo # End +--echo # +--echo # BUG#934342: outer join + semijoin materialization +--echo # + join_cache_level > 2 +--echo # + +CREATE TABLE t1 (a varchar(1), b varchar(1), INDEX idx_a(a) ); +INSERT INTO t1 VALUES ('v','v'), ('w','w'), ('t','t'); + +CREATE TABLE t2 (c varchar(1), INDEX idx_c(c) ); +INSERT INTO t2 VALUES ('v'), ('v'), ('s'), ('j'); + +CREATE TABLE t3 (c varchar(1), d varchar(1), INDEX idx_c(c) ); +INSERT INTO t3 VALUES ('v','v'), ('v','v'), ('s','s'), ('j','j'); +INSERT INTO t3 VALUES ('m','m'), ('d','d'), ('k','k'), ('m','m'); + +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; + +set join_cache_level=0; + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +set join_cache_level=6; + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t2 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +EXPLAIN +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); +SELECT * FROM t1 LEFT JOIN t3 ON (c = b) + WHERE (a, b) IN (SELECT a, b FROM t1 t); + +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; + +DROP TABLE t1,t2,t3; + +--echo # End + set join_cache_level=default; show variables like 'join_cache_level'; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8eb29853e8d..d8c4ebddc29 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1266,9 +1266,20 @@ JOIN::optimize() Item *ref_item= *ref_item_ptr; if (!ref_item->used_tables() && !(select_options & SELECT_DESCRIBE)) continue; - COND_EQUAL *equals= tab->first_inner ? tab->first_inner->cond_equal : - cond_equal; - ref_item= substitute_for_best_equal_field(tab, ref_item, equals, map2table); + COND_EQUAL *equals= cond_equal; + JOIN_TAB *first_inner= tab->first_inner; + while (equals) + { + ref_item= substitute_for_best_equal_field(tab, ref_item, + equals, map2table); + if (first_inner) + { + equals= first_inner->cond_equal; + first_inner= first_inner->first_upper; + } + else + equals= 0; + } ref_item->update_used_tables(); if (*ref_item_ptr != ref_item) { @@ -9213,7 +9224,7 @@ uint check_join_cache_usage(JOIN_TAB *tab, Check whether table tab and the previous one belong to the same nest of inner tables and if so do not use join buffer when joining table tab. */ - if (tab->first_inner) + if (tab->first_inner && tab != tab->first_inner) { for (JOIN_TAB *first_inner= tab[-1].first_inner; first_inner; @@ -9223,7 +9234,7 @@ uint check_join_cache_usage(JOIN_TAB *tab, goto no_join_cache; } } - else if (tab->first_sj_inner_tab && + else if (tab->first_sj_inner_tab && tab != tab->first_sj_inner_tab && tab->first_sj_inner_tab == tab[-1].first_sj_inner_tab) goto no_join_cache; } From 3ef46370e9719f12e0f8542ab69063eca3922205 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 18 Feb 2012 19:11:57 -0800 Subject: [PATCH 11/21] Fixed bug #934348. This bug is the result of an incomplete/inconsistent change introduced into 5.3 code when the cond_equal parameter were added to the function optimize_cond. The change was made during a merge from 5.2 in October 2010. The bug could affect only queries with HAVING. --- mysql-test/r/subselect_sj_jcl6.result | 43 +++++++++++++++++++++++++++ mysql-test/t/subselect_sj_jcl6.test | 38 +++++++++++++++++++++++ sql/sql_select.cc | 5 ++-- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/subselect_sj_jcl6.result b/mysql-test/r/subselect_sj_jcl6.result index 4ac15ea654f..769373429da 100644 --- a/mysql-test/r/subselect_sj_jcl6.result +++ b/mysql-test/r/subselect_sj_jcl6.result @@ -2833,6 +2833,49 @@ set optimizer_switch=@tmp_optimizer_switch; set join_cache_level=@tmp_join_cache_level; DROP TABLE t1,t2,t3; # End +# +# BUG#934348: GROUP BY with HAVING + semijoin materialization +# + join_cache_level > 2 +# +CREATE TABLE t1 (a varchar(1), INDEX idx_a(a)); +INSERT INTO t1 VALUES ('c'), ('v'), ('c'); +CREATE TABLE t2 (b varchar(1)); +INSERT INTO t2 VALUES ('v'), ('c'); +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; +set join_cache_level=0; +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 2 Using temporary; Using filesort +1 PRIMARY t ref idx_a idx_a 4 test.t2.b 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +a +c +v +set join_cache_level=6; +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL distinct_key NULL NULL NULL 2 Using temporary; Using filesort +1 PRIMARY t ref idx_a idx_a 4 test.t2.b 2 Using index +2 MATERIALIZED t2 ALL NULL NULL NULL NULL 2 Using where +2 MATERIALIZED t1 ref idx_a idx_a 4 test.t2.b 2 Using index +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) +GROUP BY a HAVING a != 'z'; +a +c +v +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; +DROP TABLE t1,t2; +# End set join_cache_level=default; show variables like 'join_cache_level'; Variable_name Value diff --git a/mysql-test/t/subselect_sj_jcl6.test b/mysql-test/t/subselect_sj_jcl6.test index 9fe60cdd3d9..e86ed017951 100644 --- a/mysql-test/t/subselect_sj_jcl6.test +++ b/mysql-test/t/subselect_sj_jcl6.test @@ -170,6 +170,44 @@ DROP TABLE t1,t2,t3; --echo # End +--echo # +--echo # BUG#934348: GROUP BY with HAVING + semijoin materialization +--echo # + join_cache_level > 2 +--echo # + +CREATE TABLE t1 (a varchar(1), INDEX idx_a(a)); +INSERT INTO t1 VALUES ('c'), ('v'), ('c'); + +CREATE TABLE t2 (b varchar(1)); +INSERT INTO t2 VALUES ('v'), ('c'); + +set @tmp_otimizer_switch= @@optimizer_switch; +set @tmp_join_cache_level=@@join_cache_level; +set optimizer_switch = 'materialization=on,semijoin=on,join_cache_hashed=on'; + +set join_cache_level=0; + +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; + +set join_cache_level=6; + +EXPLAIN +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; +SELECT a FROM t1 t WHERE a IN (SELECT b FROM t1, t2 WHERE b = a) + GROUP BY a HAVING a != 'z'; + +set optimizer_switch=@tmp_optimizer_switch; +set join_cache_level=@tmp_join_cache_level; + +DROP TABLE t1,t2; + +--echo # End + set join_cache_level=default; show variables like 'join_cache_level'; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d8c4ebddc29..eb4c7f7faad 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -12695,9 +12695,8 @@ optimize_cond(JOIN *join, COND *conds, List *join_list, multiple equality contains a constant. */ DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY);); - conds= build_equal_items(join->thd, conds, NULL, join_list, - &join->cond_equal); - DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY);); + conds= build_equal_items(join->thd, conds, NULL, join_list, cond_equal); + DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY);); /* change field = field to field = const for each found field = const */ propagate_cond_constants(thd, (I_List *) 0, conds, conds); From fecad7c945f26a3677b17ae6f831ee222d6fc98a Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 20 Feb 2012 15:30:54 +0400 Subject: [PATCH 12/21] BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE - In return_zero_rows(), don't call mark_as_null_row() for semi-join materialized tables, because 1) they may have been already freed, and 2)there is no real need to call mark_as_null_row() for them. --- mysql-test/r/subselect_mat.result | 13 +++++++++++++ mysql-test/r/subselect_sj_mat.result | 13 +++++++++++++ mysql-test/t/subselect_sj_mat.test | 13 +++++++++++++ sql/sql_select.cc | 14 +++++++++++++- 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect_mat.result b/mysql-test/r/subselect_mat.result index 6f90cc868a6..4d02e5012e2 100644 --- a/mysql-test/r/subselect_mat.result +++ b/mysql-test/r/subselect_mat.result @@ -1848,6 +1848,19 @@ a b 7 5 3 3 drop table t1,t2; +# +# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +SELECT STRAIGHT_JOIN MIN(a) FROM t1 +WHERE a IN ( +SELECT a FROM t1 +WHERE 'condition'='impossible' + ); +MIN(a) +NULL +DROP TABLE t1; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/r/subselect_sj_mat.result b/mysql-test/r/subselect_sj_mat.result index 964df6735f8..b21236de7b9 100644 --- a/mysql-test/r/subselect_sj_mat.result +++ b/mysql-test/r/subselect_sj_mat.result @@ -1885,6 +1885,19 @@ a b 7 5 3 3 drop table t1,t2; +# +# BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); +SELECT STRAIGHT_JOIN MIN(a) FROM t1 +WHERE a IN ( +SELECT a FROM t1 +WHERE 'condition'='impossible' + ); +MIN(a) +NULL +DROP TABLE t1; # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; set join_cache_level=@save_join_cache_level; diff --git a/mysql-test/t/subselect_sj_mat.test b/mysql-test/t/subselect_sj_mat.test index 0840029c5e0..0d04b3f984a 100644 --- a/mysql-test/t/subselect_sj_mat.test +++ b/mysql-test/t/subselect_sj_mat.test @@ -1545,6 +1545,19 @@ select * from t1 where t1.a in (select a from t2 where t2.a=7 or t2.b<=1); drop table t1,t2; +--echo # +--echo # BUG#933407: Valgrind warnings in mark_as_null_row with materialization+semijoin, STRAIGHT_JOIN, impossible WHERE +--echo # +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (0),(8); + +SELECT STRAIGHT_JOIN MIN(a) FROM t1 +WHERE a IN ( + SELECT a FROM t1 + WHERE 'condition'='impossible' + ); + +DROP TABLE t1; --echo # This must be at the end: set optimizer_switch=@subselect_sj_mat_tmp; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8eb29853e8d..547b0b256b3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10431,10 +10431,22 @@ return_zero_rows(JOIN *join, select_result *result, List &tables, if (send_row) { + /* + Set all tables to have NULL row. This is needed as we will be evaluating + HAVING condition. + */ List_iterator ti(tables); TABLE_LIST *table; while ((table= ti++)) - mark_as_null_row(table->table); // All fields are NULL + { + /* + Don't touch semi-join materialization tables, as the above join_free() + call has freed them (and HAVING clause can't have references to them + anyway). + */ + if (!table->is_jtbm()) + mark_as_null_row(table->table); // All fields are NULL + } if (having && !having->walk(&Item::clear_sum_processor, FALSE, NULL) && having->val_int() == 0) From 3c07d04580fe5f28ff8bdabd1249b8123d7da76b Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 20 Feb 2012 14:03:44 +0200 Subject: [PATCH 13/21] Fixed lp:902654 "MariaDB consistently crashes in collect_tables on Aria checkpoint execution" This happend when you have more than 1024 open Aria tables during checkpoint. mysql-test/mysql-test-run.pl: Fixed that variable names are consistent between external and internal server. mysql-test/suite/maria/suite.pm: Test for aria-block-size instead of 'aria' as 'aria' is not set for embedded server. This should be ok for aria tests, as aria is never disabled for these. storage/maria/ma_checkpoint.c: Fixed bug when there are more than 1024 open Aria tables during checkpoint. --- mysql-test/mysql-test-run.pl | 14 ++++++++++---- mysql-test/suite/maria/suite.pm | 2 +- storage/maria/ma_checkpoint.c | 7 +++++-- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index dc03a6bf5b5..9ccfe5df054 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1758,8 +1758,11 @@ sub collect_mysqld_features { # Put variables into hash if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ ) { - # print "$1=\"$2\"\n"; - $mysqld_variables{$1}= $2; + my $name= $1; + my $value=$2; + $name =~ s/_/-/g; + # print "$name=\"$value\"\n"; + $mysqld_variables{$name}= $value; } else { @@ -1813,8 +1816,11 @@ sub collect_mysqld_features_from_running_server () # Put variables into hash if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ ) { - # print "$1=\"$2\"\n"; - $mysqld_variables{$1}= $2; + my $name= $1; + my $value=$2; + $name =~ s/_/-/g; + # print "$name=\"$value\"\n"; + $mysqld_variables{$name}= $value; } } diff --git a/mysql-test/suite/maria/suite.pm b/mysql-test/suite/maria/suite.pm index e6efcdca829..3176782404b 100644 --- a/mysql-test/suite/maria/suite.pm +++ b/mysql-test/suite/maria/suite.pm @@ -2,7 +2,7 @@ package My::Suite::Maria; @ISA = qw(My::Suite); -return "Need Aria engine" unless $::mysqld_variables{'aria'} eq "ON"; +return "Need Aria engine" unless $::mysqld_variables{'aria-block-size'} > 0; bless { }; diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c index 6576c365a47..002f2999e6c 100644 --- a/storage/maria/ma_checkpoint.c +++ b/storage/maria/ma_checkpoint.c @@ -908,6 +908,9 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) */ } translog_unlock(); + if (state_copy == state_copies) + break; /* Nothing to do */ + /** We are going to flush these states. Before, all records describing how to undo such state must be @@ -932,13 +935,13 @@ static int collect_tables(LEX_STRING *str, LSN checkpoint_start_log_horizon) if (translog_flush(state_copies_horizon)) goto err; /* now we have cached states and they are WAL-safe*/ - state_copies_end= state_copy; + state_copies_end= state_copy-1; state_copy= state_copies; } /* locate our state among these cached ones */ for ( ; state_copy->index != i; state_copy++) - DBUG_ASSERT(state_copy < state_copies_end); + DBUG_ASSERT(state_copy <= state_copies_end); /* OS file descriptors are ints which we stored in 4 bytes */ compile_time_assert(sizeof(int) <= 4); From 54cad2aae3142e8a123f0d62fc0c2bd67a1dc64a Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 20 Feb 2012 17:56:47 +0200 Subject: [PATCH 14/21] Fixed compiler warnings --- mysys/stacktrace.c | 2 +- sql/mysqld.cc | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c index dce01a0c3b9..847cc746a76 100644 --- a/mysys/stacktrace.c +++ b/mysys/stacktrace.c @@ -173,7 +173,7 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)), my_safe_printf_stderr("%s", "Error when traversing the stack, stack appears corrupt.\n"); else - my_safe_printf_stderr("%s" + my_safe_printf_stderr("%s", "Please read " "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n" "and follow instructions on how to resolve the stack trace.\n" diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9ca0080e976..63495021841 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -741,7 +741,6 @@ char *opt_logname, *opt_slow_logname; static volatile sig_atomic_t kill_in_progress; #ifdef HAVE_STACKTRACE -static my_bool opt_do_pstack; my_bool opt_stack_trace; #endif /* HAVE_STACKTRACE */ my_bool opt_expect_abort= 0; From 84a3767c1912c34e79cde72a51e4cf69d235587e Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 20 Feb 2012 17:59:42 +0200 Subject: [PATCH 15/21] Fixed issue found by buildbot mysql-test/suite/innodb/t/innodb_bug51920.test: Add another possible connect error --- mysql-test/suite/innodb/t/innodb_bug51920.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/t/innodb_bug51920.test b/mysql-test/suite/innodb/t/innodb_bug51920.test index bc3bb006c1c..3c386980ed4 100644 --- a/mysql-test/suite/innodb/t/innodb_bug51920.test +++ b/mysql-test/suite/innodb/t/innodb_bug51920.test @@ -36,7 +36,7 @@ let $wait_condition = # depending on platform. # connection con1; --- error 1317, 2006, 2013 +-- error 1317, 2006, 2013, 1927 reap; connection default; DROP TABLE bug51920; From c381e44050303cf12592ae13f401175fa7171a6f Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Mon, 20 Feb 2012 20:38:05 +0400 Subject: [PATCH 16/21] BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN - In mi_rkey(), do correct handling of case where mi_yield_and_check_if_killed() detects that the thread was killed (all other similar functions in MyISAM/Aria have slightly different code and do not have this problem). - Also fixed assignment in DBUG_ASSERT - this is 2nd variant of the fix: = make .result file smaller = run KILLable statements in a separate connection, otherwise we could end up trying to KILL the final "DROP TABLE" statement --- mysql-test/r/myisam_icp.result | 15 ++++ mysql-test/t/myisam_icp.test | 129 +++++++++++++++++++++++++++++++++ storage/myisam/mi_rkey.c | 6 +- 3 files changed, 149 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/myisam_icp.result b/mysql-test/r/myisam_icp.result index 3171753adb4..d7442608b59 100644 --- a/mysql-test/r/myisam_icp.result +++ b/mysql-test/r/myisam_icp.result @@ -909,4 +909,19 @@ c NULL NULL c NULL NULL SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3,t4; +# +# BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN +# +CREATE TABLE t1 ( +b INT, +c VARCHAR(1) NOT NULL, +d DATETIME, +KEY (c, b) +) ENGINE=MyISAM; +# INSERT some data +CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES +(7),(3),(7),(3); +# Now run a number of ICP queries while trying to kill them +DROP TABLE t1,t2; set optimizer_switch=@myisam_icp_tmp; diff --git a/mysql-test/t/myisam_icp.test b/mysql-test/t/myisam_icp.test index 0e306a850c5..39a22d00a1a 100644 --- a/mysql-test/t/myisam_icp.test +++ b/mysql-test/t/myisam_icp.test @@ -262,4 +262,133 @@ SET optimizer_switch=@save_optimizer_switch; DROP TABLE t1,t2,t3,t4; +--echo # +--echo # BUG#933412: Server crashes in _mi_put_key_in_record on KILL QUERY with ICP, STRAIGHT_JOIN +--echo # +CREATE TABLE t1 ( + b INT, + c VARCHAR(1) NOT NULL, + d DATETIME, + KEY (c, b) +) ENGINE=MyISAM; +--echo # INSERT some data +--disable_query_log +INSERT INTO t1 ( b, d, c ) VALUES +(4,'2005-01-08 00:00:00','f'), +(1,'2004-05-20 10:45:51','c'),(2,'2006-08-11 21:33:49','e'), +(5,'2003-05-19 00:20:40','a'),(3,'2005-01-03 06:18:39','a'), +(7,'2008-11-25 18:18:14','b'),(6,'2008-11-09 15:53:46','b'), +(9,'2003-03-01 03:40:36','c'),(8,'2003-09-25 23:14:09','d'), +(0,'2007-01-17 09:18:31','f'),(9,'2008-09-08 09:52:24','c'), +(2,'2008-03-10 00:00:00','a'),(0,'2003-03-14 09:31:07','c'), +(4,'2005-04-25 00:00:00','h'),(6,'2001-08-01 05:55:55','e'), +(3,'2005-04-09 01:22:48','f'),(7,'2009-11-12 13:27:22','r'), +(0,'2009-03-28 05:05:28','h'),(15,'2005-05-16 04:35:41','f'), +(7,'2006-03-26 05:19:58','c'),(9,'2002-10-06 02:17:00','g'), +(4,'2007-01-28 03:28:20','b'),(1,'2009-04-22 10:16:40','c'), +(2,'2003-01-01 19:39:00','f'),(0,'2008-05-03 19:16:29','t'), +(2,'2005-01-28 00:00:00','j'),(8,'2004-01-10 00:00:00','w'), +(8,'2000-06-13 21:56:37','a'),(5,'2001-03-21 19:24:49','o'), +(99,'2003-12-20 21:29:06','f'),(0,'1900-01-01 00:00:00','w'), +(7,'2000-12-19 00:00:00','c'),(0,'2000-03-03 06:10:19','l'), +(3,'2000-08-11 00:00:00','q'),(0,'2007-05-25 03:46:41','e'), +(241,'2005-05-17 00:00:00','j'),(4,'2005-11-02 00:44:06','r'), +(43,'2001-07-11 00:00:00','a'),(1,'2008-12-01 18:30:27','z'), +(4,'2004-10-25 00:00:00','i'),(5,'2000-04-08 12:12:01','c'), +(0,'1900-01-01 00:00:00','f'),(9,'2002-05-13 22:47:02','p'), +(1,'2008-10-09 15:39:40','d'),(3,'2004-06-24 00:00:00','d'), +(0,'2008-03-06 00:00:00','r'),(9,'2007-04-16 18:40:03','i'), +(3,'2008-03-16 19:49:37','t'),(7,'2003-07-15 08:11:21','d'), +(8,'2005-02-11 00:04:53','r'),(0,'2002-09-21 00:00:00','y'), +(3,'2004-11-03 00:37:21','z'),(6,'2007-10-18 00:00:00','e'), +(6,'2007-01-21 10:42:56','o'),(5,'2000-03-26 21:21:04','b'), +(9,'2001-03-15 08:08:21','e'),(1,'2001-10-16 12:56:59','a'), +(6,'2004-05-01 23:45:55','o'),(4,'2000-03-04 00:00:00','f'), +(9,'2002-12-03 16:48:28','e'),(8,'2003-01-09 00:36:07','m'), +(1,'2006-06-22 04:32:41','s'),(8,'2008-09-20 05:01:48','q'), +(4,'2006-06-02 22:15:31','g'),(2,'2002-05-14 07:07:42','e'), +(7,'2005-06-05 01:30:42','r'),(127,'2004-05-11 01:56:48','a'), +(210,'2003-11-05 00:41:34','z'),(5,'1900-01-01 00:00:00','h'), +(1,'2006-04-16 00:00:00','f'),(7,'2000-12-17 00:00:00','x'), +(8,'2009-05-09 20:43:07','b'),(175,'2008-11-26 16:33:09','p'), +(0,'2002-05-09 21:18:44','v'),(8,'2002-06-01 11:32:25','k'), +(1,'2008-11-09 23:56:00','a'),(0,'2008-01-08 10:18:46','c'), +(2,'2005-04-16 00:00:00','o'),(5,'2002-08-25 00:00:00','b'), +(64,'2005-12-05 21:51:52','b'),(4,'2005-08-10 00:00:00','i'), +(6,'2006-03-23 00:00:00','d'),(9,'2007-01-27 00:00:00','i'), +(8,'2008-08-16 00:00:00','a'),(7,'2003-01-16 12:13:18','k'), +(0,'2003-06-22 00:00:00','v'),(5,'2008-06-20 05:43:56','u'), +(8,'2004-09-23 18:57:17','e'),(1,'2000-12-26 00:00:00','y'), +(4,'2009-06-01 13:00:28','e'),(1,'2009-11-18 06:28:48','m'), +(0,'2004-06-12 10:01:10','e'),(2,'2005-10-16 01:48:55','e'), +(5,'2001-12-23 09:50:21','l'),(6,'1900-01-01 00:00:00','a'), +(1,'2001-10-28 00:00:00','d'),(1,'2008-07-12 23:30:19','s'), +(0,'2002-10-11 16:51:16','r'),(4,'2007-09-18 06:27:10','x'), +(1,'2007-02-21 12:28:14','e'),(6,'2001-09-16 00:00:00','f'), +(0,'2007-09-20 02:25:45','c'),(0,'2006-08-07 03:25:56','j'), +(8,'2006-12-04 20:20:32','t'),(7,'2007-09-05 10:13:10','i'), +(9,'2006-04-12 17:59:57','t'),(2,'2009-04-28 00:06:09','b'), +(8,'2000-01-07 00:00:00','b'),(7,'2000-03-25 10:04:41','k'), +(4,'2000-07-10 00:44:55','w'),(9,'2007-09-22 14:26:26','j'), +(9,'2003-09-11 22:41:17','a'),(0,'2004-06-07 13:52:32','c'), +(8,'2008-10-09 00:00:00','p'),(1,'2007-04-01 00:00:00','c'), +(9,'2000-12-05 00:00:00','i'),(3,'1900-01-01 00:00:00','a'), +(3,'2005-12-24 21:50:54','e'),(8,'2009-07-21 19:34:55','n'), +(9,'2005-11-13 17:57:56','d'),(7,'2004-10-07 06:41:39','l'), +(1,'2004-11-20 08:05:08','u'),(3,'2005-05-25 00:00:00','r'), +(1,'2006-09-02 14:16:41','u'),(8,'2006-01-07 00:00:00','a'), +(9,'2003-04-05 00:54:20','w'),(2,'2003-12-22 00:00:00','a'), +(9,'2006-04-16 17:31:40','e'),(6,'2005-02-10 14:22:46','e'), +(7,'2004-04-27 05:54:52','p'),(1,'2005-12-07 00:00:00','t'), +(5,'2004-04-03 20:56:28','d'),(4,'2000-09-07 05:17:16','h'), +(2,'2004-08-04 16:10:42','i'),(1,'2007-03-04 00:00:00','b'), +(9,'1900-01-01 00:00:00','d'),(1,'2000-05-12 23:02:50','m'), +(2,'1900-01-01 00:00:00','l'),(1,'1900-01-01 00:00:00','k'), +(4,'2000-07-14 01:25:18','d'),(5,'2009-08-21 00:00:00','w'), +(6,'2009-05-25 13:33:54','f'),(7,'2006-06-13 00:00:00','e'), +(8,'1900-01-01 00:00:00','a'),(6,'2004-02-24 00:00:00','j'), +(0,'2003-05-21 07:03:46','k'),(9,'1900-01-01 00:00:00','e'), +(2,'1900-01-01 00:00:00','y'),(2,'2000-12-22 00:00:00','e'), +(3,'2003-09-26 00:00:00','f'),(2,'2001-01-13 08:20:19','h'), +(9,'2008-09-23 20:03:28','n'),(5,'2007-03-20 02:41:38','s'), +(1,'2009-02-14 10:27:18','a'),(0,'2001-08-10 17:44:05','s'), +(3,'2008-01-20 12:49:54','v'),(1,'2001-05-05 09:09:59','r'); +--enable_query_log +CREATE TABLE t2 ( a INT ) ENGINE=MyISAM; +INSERT INTO t2 VALUES + (7),(3),(7),(3); + +# 'con2' will be the connection that will run all the KILLable statements +--connect (con2,127.0.0.1,root,,test) + +--let $run = 300 +--let $con_id = `SELECT CONNECTION_ID()` + +--echo # Now run a number of ICP queries while trying to kill them +--disable_query_log +--disable_result_log +while ($run) +{ + --send + SELECT * FROM t1 AS alias1 STRAIGHT_JOIN t1 AS alias2 + ON alias2.c = alias1.c + WHERE alias2.b >= 9; + + --connect (con1,127.0.0.1,root,,test) + --eval KILL QUERY $con_id + --disconnect con1 + + --dec $run + + --connection con2 + --error 0,ER_QUERY_INTERRUPTED + --reap +} +--enable_result_log +--enable_query_log +--disconnect con2 +--connection default +DROP TABLE t1,t2; + set optimizer_switch=@myisam_icp_tmp; + diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c index dbe4d59ee90..d2af9a3e5ed 100644 --- a/storage/myisam/mi_rkey.c +++ b/storage/myisam/mi_rkey.c @@ -157,7 +157,11 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, mi_yield_and_check_if_killed(info, inx)) { /* Aborted by user */ + DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR && + my_errno == HA_ERR_ABORTED_BY_USER); + res= ICP_ERROR; buf= 0; /* Fast abort */ + break; } } if (res == ICP_OUT_OF_RANGE) @@ -179,7 +183,7 @@ int mi_rkey(MI_INFO *info, uchar *buf, int inx, const uchar *key, } else { - DBUG_ASSERT(info->lastpos= HA_OFFSET_ERROR); + DBUG_ASSERT(info->lastpos == HA_OFFSET_ERROR); } } if (share->concurrent_insert) From e7fef1df58559f29c16a4571d4218ff291a8050e Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 20 Feb 2012 18:07:38 +0100 Subject: [PATCH 17/21] Fix compilation on Windows, and various Windows related mistakes introduced by "safe exception patch". Remove misleading comments suggesting about signal() Windows, the routine here is part of a exception handler, and sig parameter is an exception code. --- sql/signal_handler.cc | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 23d898fdb5e..6406cd3bae0 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -28,7 +28,7 @@ #endif /* - We are handling signals in this file. + We are handling signals/exceptions in this file. Any global variables we read should be 'volatile sig_atomic_t' to guarantee that we read some consistent value. */ @@ -40,20 +40,18 @@ extern volatile sig_atomic_t ld_assume_kernel_is_set; #endif /** - * Handler for fatal signals + * Handler for fatal signals on POSIX, exception handler on Windows. * * Fatal events (seg.fault, bus error etc.) will trigger * this signal handler. The handler will try to dump relevant * debugging information to stderr and dump a core image. * - * Signal handlers can only use a set of 'safe' system calls - * and library functions. A list of safe calls in POSIX systems + * POSIX : Signal handlers should, if possible, only use a set of 'safe' system + * calls and library functions. A list of safe calls in POSIX systems * are available at: * http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html - * For MS Windows, guidelines are available at: - * http://msdn.microsoft.com/en-us/library/xdkz3x12(v=vs.71).aspx * - * @param sig Signal number + * @param sig Signal number /Exception code */ extern "C" sig_handler handle_fatal_signal(int sig) { @@ -77,7 +75,13 @@ extern "C" sig_handler handle_fatal_signal(int sig) my_safe_printf_stderr("%02d%02d%02d %2d:%02d:%02d ", tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - if (opt_expect_abort && sig == SIGABRT) + if (opt_expect_abort +#ifdef _WIN32 + && sig == EXCEPTION_BREAKPOINT /* __debugbreak in my_sigabrt_hander() */ +#else + && sig == SIGABRT +#endif + ) { fprintf(stderr,"[Note] mysqld did an expected abort\n"); goto end; @@ -252,5 +256,7 @@ end: On Windows, do not terminate, but pass control to exception filter. */ _exit(1); // Using _exit(), since exit() is not async signal safe +#else + return; #endif } From 7ed4806b1181c1f003d2d31f997a4ca6609ee794 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 21 Feb 2012 01:44:50 +0200 Subject: [PATCH 18/21] More general handling of memory loss in dlclose (backported from 5.2) Fixed supression in mysql-test-run so it also works on windows. mysql-test/mysql-test-run.pl: Fixed supression so it also works on windows. mysql-test/valgrind.supp: More general handling of memory loss in dlclose (backported from 5.2) sql/signal_handler.cc: Added newlines around link to how to do bug reports --- mysql-test/mysql-test-run.pl | 4 +- mysql-test/valgrind.supp | 130 ++--------------------------------- sql/signal_handler.cc | 4 +- 3 files changed, 11 insertions(+), 127 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index cb6f7b4a486..3e1be3ab077 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -4443,9 +4443,9 @@ sub extract_warning_lines ($) { qr/Failed on request_dump/, qr/Slave: Can't drop database.* database doesn't exist/, qr/Slave: Operation DROP USER failed for 'create_rout_db'/, - qr|Checking table: '\./mtr/test_suppressions'|, + qr|Checking table: '\..mtr.test_suppressions'|, qr|Table \./test/bug53592 has a primary key in InnoDB data dictionary, but not in MySQL|, - qr|mysqld: Table '\./mtr/test_suppressions' is marked as crashed and should be repaired|, + qr|mysqld: Table '\..mtr.test_suppressions' is marked as crashed and should be repaired|, qr|InnoDB: Error: table 'test/bug39438'|, qr|table.*is full|, ); diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index ff649db144a..e7f5a7880d2 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -386,134 +386,18 @@ fun:__libc_start_main } +# +# dlclose can allocate memory for error message, the memory will be +# freed by dlerror or other dl* function. +# { - dlclose memory loss from udf_free + memory "loss" from dlclose error messages Memcheck:Leak - fun:calloc - fun:_dlerror_run + fun:*alloc + ... fun:dlclose - fun:_Z8udf_freev } -{ - dlsym memory loss from udf_free on SuSE 11.1 x64 variant 2 - Memcheck:Leak - fun:calloc - obj:/lib*/ld-*.so - fun:dlclose - fun:udf_free -} - -{ - dlclose memory loss from plugin variant 1 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:plugin_dl_del(st_mysql_lex_string const*) -} - -{ - dlclose memory loss from plugin variant 2 - Memcheck:Leak - fun:malloc - fun:_dl_close_worker - fun:_dl_close - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 3 - Memcheck:Leak - fun:malloc - fun:_dl_scope_free - fun:_dl_close_worker - fun:_dl_close - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 4 - Memcheck:Leak - fun:malloc - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/libdl-*.so - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 5 - Memcheck:Leak - fun:malloc - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/ld-*.so - obj:/lib*/libdl-*.so - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl -} - -{ - dlclose memory loss from plugin variant 6, seen on Ubuntu Jaunty i686 - Memcheck:Leak - fun:malloc - fun:_dl_scope_free - fun:_dl_close_worker - fun:_dl_close - fun:dlclose_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 7, seen on Ubuntu Jaunty i686 - Memcheck:Leak - fun:malloc - fun:_dl_close_worker - fun:_dl_close - fun:dlclose_doit - fun:_dl_catch_error - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 8 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:_Z15free_plugin_memP12st_plugin_dl - fun:_Z13plugin_dl_delPK19st_mysql_lex_string -} - -{ - dlclose memory loss from plugin variant 9 - Memcheck:Leak - fun:calloc - fun:_dlerror_run - fun:dlclose - fun:_ZL15free_plugin_memP12st_plugin_dl - fun:_ZL13plugin_dl_delPK19st_mysql_lex_string -} { dlsym memory loss from plugin on SuSE 11.1 x64 diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 23d898fdb5e..289670ec830 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -88,10 +88,10 @@ extern "C" sig_handler handle_fatal_signal(int sig) my_safe_printf_stderr("%s", "This could be because you hit a bug. It is also possible that this binary\n" "or one of the libraries it was linked against is corrupt, improperly built,\n" - "or misconfigured. This error can also be caused by malfunctioning hardware.\n"); + "or misconfigured. This error can also be caused by malfunctioning hardware.\n\n"); my_safe_printf_stderr("%s", - "To report this bug, see http://kb.askmonty.org/en/reporting-bugs\n"); + "To report this bug, see http://kb.askmonty.org/en/reporting-bugs\n\n"); my_safe_printf_stderr("%s", "We will try our best to scrape up some info that will hopefully help\n" From f4885c092e3414cb4274e055310f27eae1d28819 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 21 Feb 2012 01:46:51 +0200 Subject: [PATCH 19/21] Added missing signal values to signal_handler.cc sql/signal_handler.cc: Added missing signal values. --- sql/signal_handler.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc index 23d898fdb5e..13396551e7d 100644 --- a/sql/signal_handler.cc +++ b/sql/signal_handler.cc @@ -173,6 +173,12 @@ extern "C" sig_handler handle_fatal_signal(int sig) case THD::KILL_QUERY: kreason= "KILL_QUERY"; break; + case THD::KILL_SYSTEM_THREAD: + kreason= "KILL_SYSTEM_THREAD"; + break; + case THD::KILL_SERVER: + kreason= "KILL_SERVER"; + break; case THD::KILLED_NO_VALUE: kreason= "KILLED_NO_VALUE"; break; From 3608ec3036fba4921c11e3d2caa3584c41975187 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Tue, 21 Feb 2012 09:35:46 +0200 Subject: [PATCH 20/21] Fixed wrong test case mysql-test/suite/innodb_plugin/t/innodb_gis.test: Don't run test if innodb_plugin isn't used. --- mysql-test/suite/innodb_plugin/t/innodb_gis.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/innodb_plugin/t/innodb_gis.test b/mysql-test/suite/innodb_plugin/t/innodb_gis.test index dec0c8bf725..ad1d081f29c 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_gis.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_gis.test @@ -1,3 +1,4 @@ +--source include/have_innodb_plugin.inc SET storage_engine=innodb; --source include/gis_generic.inc --source include/gis_keys.inc From 446554a15bd84f39ec4a8163e9f4456fa9be8fb2 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 20 Feb 2012 21:30:23 +0100 Subject: [PATCH 21/21] fix for "relocation R_X86_64_PC32 against `handler_index_cond_check' can not be used when making a shared object; recompile with -fPIC" don't use visibility=hidden for external functions --- storage/xtradb/include/ha_prototypes.h | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h index 28c28838400..df7d71af6cf 100644 --- a/storage/xtradb/include/ha_prototypes.h +++ b/storage/xtradb/include/ha_prototypes.h @@ -250,7 +250,6 @@ innobase_get_at_most_n_mbchars( /*************************************************************//** InnoDB index push-down condition check @return ICP_NO_MATCH, ICP_MATCH, or ICP_OUT_OF_RANGE */ -UNIV_INTERN enum icp_result handler_index_cond_check( /*================*/