From bad3e4179c5471728fb0dc3d72b81db02129128f Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 19 Dec 2011 14:55:30 -0800 Subject: [PATCH 01/28] Fixed LP bug #906322. If the sorted table belongs to a dependent subquery then the function create_sort_index() should not clear TABLE:: select and TABLE::select for this table after the sort of the table has been performed, because these members are needed for the second execution of the subquery. --- mysql-test/r/subselect.result | 2 -- mysql-test/suite/innodb/r/innodb_mysql.result | 6 +++--- mysql-test/suite/innodb_plugin/r/innodb_mysql.result | 6 +++--- sql/sql_select.cc | 2 -- 4 files changed, 6 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 1a56940a560..1f3432ecde1 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4631,8 +4631,6 @@ SELECT * FROM t1 WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); pk a 1 10 -3 30 -2 20 DROP TABLE t1,t2; CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b)); INSERT INTO t1 VALUES (1,NULL), (9,NULL); diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 42aca8b6464..666d6b7591f 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -1739,7 +1739,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 5 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 5 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) ENGINE=InnoDB; @@ -1753,7 +1753,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 9 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 9 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), KEY (c3), KEY (c2, c3)) @@ -1768,7 +1768,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 7 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 7 5 Using where; Using filesort DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index 86d83f82b76..987a04eb59d 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -1739,7 +1739,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 5 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 5 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) ENGINE=InnoDB; @@ -1753,7 +1753,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 9 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 9 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), KEY (c3), KEY (c2, c3)) @@ -1768,7 +1768,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 7 5 Using filesort +2 DERIVED t1 ALL c3,c2 c3 7 5 Using where; Using filesort DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3e6fac841b2..219e0ebe406 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -14466,11 +14466,9 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, table->sort.io_cache= NULL; select->cleanup(); // filesort did select - tab->select= 0; table->quick_keys.clear_all(); // as far as we cleanup select->quick table->sort.io_cache= tablesort_result_cache; } - tab->select_cond=0; tab->last_inner= 0; tab->first_unmatched= 0; tab->type=JT_ALL; // Read with normal read_record From 27380e4fb522062daa0d7775a3205363a5c1b110 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 20 Dec 2011 01:56:41 -0800 Subject: [PATCH 02/28] Fixed LP bug #794005. The function st_table::mark_virtual_columns_for_write() did not take into account the fact that for any table the value of st_table::vfield is 0 when there are no virtual columns in the table definition. --- mysql-test/r/view.result | 11 +++++++++++ mysql-test/t/view.test | 16 ++++++++++++++++ sql/table.cc | 3 +++ 3 files changed, 30 insertions(+) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 40142c5e0a7..22fd4eb1722 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -3926,3 +3926,14 @@ drop table t1,t2; # ----------------------------------------------------------------- # -- End of 5.1 tests. # ----------------------------------------------------------------- +# +# Bug #794005: crash in st_table::mark_virtual_columns_for_write +# +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +CREATE VIEW v2 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM v2; +CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; +UPDATE v1 SET a = 10; +DROP VIEW v1,v2; +DROP TABLE t1,t2; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 644fbe0443f..462118af4ea 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -3976,3 +3976,19 @@ drop table t1,t2; --echo # ----------------------------------------------------------------- --echo # -- End of 5.1 tests. --echo # ----------------------------------------------------------------- + +--echo # +--echo # Bug #794005: crash in st_table::mark_virtual_columns_for_write +--echo # + +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); + +CREATE VIEW v2 AS SELECT * FROM t2; +CREATE VIEW v1 AS SELECT * FROM v2; +CREATE OR REPLACE ALGORITHM = TEMPTABLE VIEW v2 AS SELECT * FROM t1; + +UPDATE v1 SET a = 10; + +DROP VIEW v1,v2; +DROP TABLE t1,t2; diff --git a/sql/table.cc b/sql/table.cc index ca5e4678c52..ca14b2ef4d2 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5161,6 +5161,9 @@ void st_table::mark_virtual_columns_for_write(bool insert_fl) Field **vfield_ptr, *tmp_vfield; bool bitmap_updated= FALSE; + if (!vfield) + return; + for (vfield_ptr= vfield; *vfield_ptr; vfield_ptr++) { tmp_vfield= *vfield_ptr; From 7b29727a5a730d9baef822418e899f8ac5302587 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Dec 2011 12:45:53 +0200 Subject: [PATCH 03/28] Supression condition made wider to cover some other system cases. --- mysql-test/valgrind.supp | 130 +++------------------------------------ 1 file changed, 7 insertions(+), 123 deletions(-) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 26e2c1261ab..30d77fa3e72 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 From 2be9a419f5e680dbb9b02fe6ce1f07d2442ae938 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Wed, 21 Dec 2011 13:23:15 +0200 Subject: [PATCH 04/28] Fixes lp:907049 "Server started with skip-aria crashes on an attempt to connect to it" sql/sql_parse.cc: Only call ha_maria::implicit_commit if aria is enabled --- sql/sql_parse.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 41f308a2ce4..8c51ea69618 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -190,7 +190,8 @@ bool end_active_trans(THD *thd) if (ha_commit(thd)) error=1; #ifdef WITH_MARIA_STORAGE_ENGINE - ha_maria::implicit_commit(thd, TRUE); + if (ha_storage_engine_is_enabled(maria_hton)) + ha_maria::implicit_commit(thd, TRUE); #endif } thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); @@ -1297,6 +1298,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char *beginning_of_next_stmt= (char*) end_of_stmt; #ifdef WITH_MARIA_STORAGE_ENGINE + if (ha_storage_engine_is_enabled(maria_hton)) ha_maria::implicit_commit(thd, FALSE); #endif @@ -1722,7 +1724,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->transaction.stmt.reset(); #ifdef WITH_MARIA_STORAGE_ENGINE - ha_maria::implicit_commit(thd, FALSE); + if (ha_storage_engine_is_enabled(maria_hton)) + ha_maria::implicit_commit(thd, FALSE); #endif if (!(sql_command_flags[thd->lex->sql_command] & CF_CHANGES_DATA)) From a5e92c7e6d8a6540a63038e4b982599cec2d077f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 22 Dec 2011 11:07:04 +0100 Subject: [PATCH 05/28] compilation warning - unused variable --- storage/maria/ha_maria.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 99a1e2cc903..04a97da9d8d 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2430,8 +2430,8 @@ int ha_maria::extra_opt(enum ha_extra_function operation, ulong cache_size) int ha_maria::delete_all_rows() { - THD *thd= table->in_use; #ifdef EXTRA_DEBUG + THD *thd= table->in_use; TRN *trn= file->trn; if (trn && ! (trnman_get_flags(trn) & TRN_STATE_INFO_LOGGED)) { From 0e8f71b2bcd8430fa0f1677fa605a6b0fc5daf7b Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 22 Dec 2011 15:50:33 +0100 Subject: [PATCH 06/28] LPBUG#906638 : Fixes to build oqgraph with boost 1.48 - dijkstra_shortest_paths() needs a Graph as first parameter, in case of reverse_graph we now need to use its m_g member - use boost::tuples::tie() on all places where tie() was used . Reason - fix the build with Visual Studio 10 SP1 (which includes std:tr1:tie, thus creating ambiguity) --- storage/oqgraph/graphcore.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/storage/oqgraph/graphcore.cc b/storage/oqgraph/graphcore.cc index 0b856ac253f..ba179989ea3 100644 --- a/storage/oqgraph/graphcore.cc +++ b/storage/oqgraph/graphcore.cc @@ -414,7 +414,7 @@ namespace open_query { if (record_weight && u != v) { typename graph_traits::out_edge_iterator ei, ei_end; - for (tie(ei, ei_end)= out_edges(v, g); ei != ei_end; ++ei) + for (boost::tuples::tie(ei, ei_end)= out_edges(v, g); ei != ei_end; ++ei) { if (target(*ei, g) == u) { @@ -479,14 +479,14 @@ namespace open_query if (in_degree(dest, g) >= out_degree(orig, g)) { graph_traits::out_edge_iterator ei, ei_end; - tie(ei, ei_end)= out_edges(orig, g); + boost::tuples::tie(ei, ei_end)= out_edges(orig, g); if ((ei= find_if(ei, ei_end, target_equals(dest, g))) != ei_end) return *ei; } else { graph_traits::in_edge_iterator ei, ei_end; - tie(ei, ei_end)= in_edges(dest, g); + boost::tuples::tie(ei, ei_end)= in_edges(dest, g); if ((ei= find_if(ei, ei_end, source_equals(orig, g))) != ei_end) return *ei; } @@ -727,7 +727,7 @@ namespace open_query if ((cursor= new (std::nothrow) stack_cursor(share)) && orig) { graph_traits::out_edge_iterator ei, ei_end; - for (tie(ei, ei_end)= out_edges(*orig, share->g); ei != ei_end; ++ei) + for (boost::tuples::tie(ei, ei_end)= out_edges(*orig, share->g); ei != ei_end; ++ei) { Vertex v= target(*ei, share->g); static_cast(cursor)-> @@ -741,7 +741,7 @@ namespace open_query dest) { graph_traits::in_edge_iterator ei, ei_end; - for (tie(ei, ei_end)= in_edges(*dest, share->g); ei != ei_end; ++ei) + for (boost::tuples::tie(ei, ei_end)= in_edges(*dest, share->g); ei != ei_end; ++ei) { Vertex v= source(*ei, share->g); static_cast(cursor)-> @@ -876,7 +876,7 @@ namespace open_query switch (ALGORITHM & op) { case DIJKSTRAS: - dijkstra_shortest_paths(r, *dest, + dijkstra_shortest_paths(r.m_g, *dest, weight_map( share->weightmap ). @@ -1067,7 +1067,7 @@ int edges_cursor::fetch_row(const row &row_info, row &result) edge_iterator it, end; reference ref; size_t count= position; - for (tie(it, end)= edges(share->g); count && it != end; ++it, --count) + for (boost::tuples::tie(it, end)= edges(share->g); count && it != end; ++it, --count) ; if (it != end) ref= reference(position+1, *it); From c9259f166bfcc757338c957f806e3d18637da17a Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 27 Dec 2011 13:19:13 -0800 Subject: [PATCH 07/28] Fixed LP bug #904345. The MIN/MAX optimizer code from the function opt_sum_query erroneously did not take into account conjunctive conditions that did not depend on any table, yet were not identified as constant items. These could be items containing rand() or PS/SP parameters. These items are supposed to be evaluated at the execution phase. That's why if such conditions can be extracted from the WHERE condition the MIN/MAX optimization is not applied as currently it is always done at the optimization phase. (In 5.3 expensive subqueries are also evaluated only at the execution phase. So, if a constant condition with such subquery can be extracted from the WHERE clause the MIN/MAX optimization should not be applied in 5.3.) IF an IN/ALL/SOME predicate with a constant left part is transformed into an EXISTS subquery the resulting subquery should not be considered uncacheable if the right part of the predicate is not uncacheable. Backported the function dbug_print_item() from 5.3. The function is used only for debugging. --- mysql-test/r/func_group.result | 40 +++++++++++++++++++++++- mysql-test/r/ps_11bugs.result | 6 ++-- mysql-test/r/select.result | 8 ++--- mysql-test/r/select_pkeycache.result | 8 ++--- mysql-test/r/subselect.result | 14 ++++----- mysql-test/suite/pbxt/r/ps_11bugs.result | 6 ++-- mysql-test/suite/pbxt/r/select.result | 8 ++--- mysql-test/suite/pbxt/r/subselect.result | 4 +-- mysql-test/t/func_group.test | 27 +++++++++++++++- sql/item.cc | 21 +++++++++++++ sql/item_subselect.cc | 13 +++++--- sql/opt_sum.cc | 3 +- 12 files changed, 123 insertions(+), 35 deletions(-) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 2ff1cd2ec4a..de5672941c7 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1767,4 +1767,42 @@ MAX(a) 10 drop table t1; # -End of 5.1 tests +# Bug #904345: MIN/MAX optimization with constant FALSE condition +# +CREATE TABLE t1 (a int NOT NULL, KEY(a)); +INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9); +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES +(8,2), (6,9), (8,4), (5,3), (9,1); +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +Warnings: +Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where 0 +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +MAX(a) +NULL +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY t2 ALL NULL NULL NULL NULL 5 100.00 Using where +Warnings: +Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where 0 +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; +MAX(a) +NULL +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 range a a 4 NULL 4 100.00 Using where; Using index +Warnings: +Note 1003 select max(`test`.`t1`.`a`) AS `MAX(a)` from `test`.`t1` where (((rand() * 0) <> 0) and (`test`.`t1`.`a` < 10)) +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; +MAX(a) +NULL +DROP TABLE t1,t2; +# +End of 5.2 tests diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result index 5c11163ab9e..3b4d525aeb4 100644 --- a/mysql-test/r/ps_11bugs.result +++ b/mysql-test/r/ps_11bugs.result @@ -120,9 +120,9 @@ create table t1 (a int primary key); insert into t1 values (1); explain select * from t1 where 3 in (select (1+1) union select 1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible HAVING -3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +3 UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING NULL UNION RESULT ALL NULL NULL NULL NULL NULL select * from t1 where 3 in (select (1+1) union select 1); a diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 5453345d50c..e2c2dcaced4 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2778,10 +2778,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.615800023078918 @@ -2800,10 +2800,10 @@ max(key1) min(key2) 0.615800023078918 1.37619996070862 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.615800023078918 +0.384499996900558 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.376199990510941 +0.384499996900558 DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); diff --git a/mysql-test/r/select_pkeycache.result b/mysql-test/r/select_pkeycache.result index 5453345d50c..e2c2dcaced4 100644 --- a/mysql-test/r/select_pkeycache.result +++ b/mysql-test/r/select_pkeycache.result @@ -2778,10 +2778,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 range key1 key1 5 NULL 3 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.615800023078918 @@ -2800,10 +2800,10 @@ max(key1) min(key2) 0.615800023078918 1.37619996070862 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.615800023078918 +0.384499996900558 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.376199990510941 +0.384499996900558 DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 1f3432ecde1..65e76d04c1f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1302,7 +1302,7 @@ SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE Warnings: Note 1003 select (0,(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)` INSERT INTO t1 (pseudo) VALUES ('test1'); @@ -1312,7 +1312,7 @@ SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE Warnings: Note 1003 select (0,(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)` drop table t1; @@ -4476,15 +4476,15 @@ INSERT INTO t1 VALUES (1),(2); EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 -2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort Warnings: -Note 1003 select 1 AS `1` from `test`.`t1` where (1,(select 1 from `test`.`t1` group by `test`.`t1`.`a` having 1)) +Note 1003 select 1 AS `1` from `test`.`t1` where 1 EXPLAIN EXTENDED SELECT 1 FROM t1 WHERE 1 IN (SELECT 1 FROM t1 WHERE a > 3 GROUP BY a); id select_type table type possible_keys key key_len ref rows filtered Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 Using where; Using temporary; Using filesort Warnings: -Note 1003 select 1 AS `1` from `test`.`t1` where (1,(select 1 from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having 1)) +Note 1003 select 1 AS `1` from `test`.`t1` where 0 DROP TABLE t1; # # Bug#45061: Incorrectly market field caused wrong result. diff --git a/mysql-test/suite/pbxt/r/ps_11bugs.result b/mysql-test/suite/pbxt/r/ps_11bugs.result index fad35b97b24..0be781bca27 100644 --- a/mysql-test/suite/pbxt/r/ps_11bugs.result +++ b/mysql-test/suite/pbxt/r/ps_11bugs.result @@ -120,9 +120,9 @@ create table t1 (a int primary key); insert into t1 values (1); explain select * from t1 where 3 in (select (1+1) union select 1); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible HAVING -3 DEPENDENT UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +3 UNION NULL NULL NULL NULL NULL NULL NULL Impossible HAVING NULL UNION RESULT ALL NULL NULL NULL NULL NULL select * from t1 where 3 in (select (1+1) union select 1); a diff --git a/mysql-test/suite/pbxt/r/select.result b/mysql-test/suite/pbxt/r/select.result index c06dd06ea3e..b98f980f821 100644 --- a/mysql-test/suite/pbxt/r/select.result +++ b/mysql-test/suite/pbxt/r/select.result @@ -2786,10 +2786,10 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +1 SIMPLE t1 index key1 key1 5 NULL 4 Using where; Using index select max(key1) from t1 where key1 <= 0.6158; max(key1) 0.615800023078918 @@ -2808,10 +2808,10 @@ max(key1) min(key2) 0.615800023078918 1.37619996070862 select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5; max(key1) -0.615800023078918 +0.384499996900558 select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5; min(key1) -0.376199990510941 +0.384499996900558 DROP TABLE t1,t2; CREATE TABLE t1 (i BIGINT UNSIGNED NOT NULL); INSERT INTO t1 VALUES (10); diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result index 0cdec48e192..63b289d259e 100644 --- a/mysql-test/suite/pbxt/r/subselect.result +++ b/mysql-test/suite/pbxt/r/subselect.result @@ -1177,7 +1177,7 @@ SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE Warnings: Note 1003 select (0,(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)` INSERT INTO t1 (pseudo) VALUES ('test1'); @@ -1187,7 +1187,7 @@ SELECT 0 IN (SELECT 1 FROM t1 a); EXPLAIN EXTENDED SELECT 0 IN (SELECT 1 FROM t1 a); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL NULL No tables used -2 DEPENDENT SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE Warnings: Note 1003 select (0,(select 1 from `test`.`t1` `a` where 0)) AS `0 IN (SELECT 1 FROM t1 a)` drop table t1; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 8c2be79ee7d..84afe328aeb 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1150,4 +1150,29 @@ SELECT MAX(a) FROM t1 WHERE a NOT BETWEEN 3 AND 9; drop table t1; --echo # ---echo End of 5.1 tests +--echo # Bug #904345: MIN/MAX optimization with constant FALSE condition +--echo # + +CREATE TABLE t1 (a int NOT NULL, KEY(a)); +INSERT INTO t1 VALUES (10), (8), (11), (7), (15), (12), (9); + +CREATE TABLE t2 (a int, b int); +INSERT INTO t2 VALUES + (8,2), (6,9), (8,4), (5,3), (9,1); + +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT 3,4) AND a<10; + +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; +SELECT MAX(a) FROM t1 WHERE (1,2) IN (SELECT a,b FROM t2 WHERE b<5) and a<10; + +EXPLAIN EXTENDED +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; +SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; + +DROP TABLE t1,t2; + +--echo # +--echo End of 5.2 tests diff --git a/sql/item.cc b/sql/item.cc index c08333e4b80..72adb9d0b52 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7915,6 +7915,27 @@ void view_error_processor(THD *thd, void *data) ((TABLE_LIST *)data)->hide_view_error(thd); } +#ifndef DBUG_OFF + +/* Debugger help function */ +static char dbug_item_print_buf[256]; + +const char *dbug_print_item(Item *item) +{ + char *buf= dbug_item_print_buf; + String str(buf, sizeof(dbug_item_print_buf), &my_charset_bin); + str.length(0); + if (!item) + return "(Item*)NULL"; + item->print(&str ,QT_ORDINARY); + if (str.c_ptr() == buf) + return buf; + else + return "Couldn't fit into buffer"; +} + +#endif /*DBUG_OFF*/ + /***************************************************************************** ** Instantiate templates *****************************************************************************/ diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index fa9eff0d95b..82d2313aa2b 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1117,8 +1117,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, (Item**)optimizer->get_cache(), (char *)"", (char *)in_left_expr_name); - - master_unit->uncacheable|= UNCACHEABLE_DEPENDENT; + if (!left_expr->const_item()) + master_unit->uncacheable|= UNCACHEABLE_DEPENDENT; } if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards) { @@ -1127,7 +1127,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, pushed_cond_guards[0]= TRUE; } - select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; + if (!left_expr->const_item()) + select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; if (join->having || select_lex->with_sum_func || select_lex->group_list.elements) { @@ -1338,7 +1339,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) optimizer->keep_top_level_cache(); thd->lex->current_select= current; - master_unit->uncacheable|= UNCACHEABLE_DEPENDENT; + if (!left_expr->const_item()) + master_unit->uncacheable|= UNCACHEABLE_DEPENDENT; if (!abort_on_null && left_expr->maybe_null && !pushed_cond_guards) { @@ -1350,7 +1352,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) } } - select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; + if (!left_expr->const_item()) + select_lex->uncacheable|= UNCACHEABLE_DEPENDENT; if (is_having_used) { /* diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index f8a81eac380..27a848cb0ec 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -608,7 +608,8 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, if (!cond) DBUG_RETURN(TRUE); Field *field= field_part->field; - if (!(cond->used_tables() & field->table->map)) + if (!(cond->used_tables() & field->table->map) && + test(cond->used_tables() & ~PSEUDO_TABLE_BITS)) { /* Condition doesn't restrict the used table */ DBUG_RETURN(TRUE); From 31805e621495e33d4dcf4e4b2180d42367f90894 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Tue, 27 Dec 2011 19:13:53 -0800 Subject: [PATCH 08/28] Fixed LP bug #879860. The MIN/MAX optimization cannot be applied to a subquery if its WHERE clause contains a conjunctive condition depending on an outer reference. --- mysql-test/r/func_group.result | 23 +++++++++++++++++++++++ mysql-test/t/func_group.test | 19 +++++++++++++++++++ sql/opt_sum.cc | 4 ++++ 3 files changed, 46 insertions(+) diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index de5672941c7..3608f587572 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1805,4 +1805,27 @@ MAX(a) NULL DROP TABLE t1,t2; # +# Bug #879860: MIN/MAX for subquery returning empty set +# +CREATE TABLE t1 (a int PRIMARY KEY); +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 (a int NOT NULL); +INSERT INTO t2 VALUES (10); +CREATE TABLE t3 ( a int, b int); +INSERT INTO t3 VALUES (19,1), (20,5); +EXPLAIN EXTENDED +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 2 100.00 +2 DEPENDENT SUBQUERY t1 system NULL NULL NULL NULL 1 100.00 +2 DEPENDENT SUBQUERY t2 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1276 Field or reference 'test.t3.b' of SELECT #2 was resolved in SELECT #1 +Note 1003 select (select min('1') from `test`.`t1` join `test`.`t2` where ('10' = `test`.`t3`.`b`)) AS `(SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b)` from `test`.`t3` +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; +(SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) +NULL +NULL +DROP TABLE t1,t2,t3; +# End of 5.2 tests diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 84afe328aeb..3939d53cb31 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -1174,5 +1174,24 @@ SELECT MAX(a) FROM t1 WHERE RAND()*0<>0 AND a<10; DROP TABLE t1,t2; +--echo # +--echo # Bug #879860: MIN/MAX for subquery returning empty set +--echo # + +CREATE TABLE t1 (a int PRIMARY KEY); +INSERT INTO t1 VALUES (1); + +CREATE TABLE t2 (a int NOT NULL); +INSERT INTO t2 VALUES (10); + +CREATE TABLE t3 ( a int, b int); +INSERT INTO t3 VALUES (19,1), (20,5); + +EXPLAIN EXTENDED +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; +SELECT (SELECT MIN(t1.a) FROM t1,t2 WHERE t2.a = t3.b) FROM t3; + +DROP TABLE t1,t2,t3; + --echo # --echo End of 5.2 tests diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 27a848cb0ec..cd6e7a4ffaa 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -608,6 +608,10 @@ static bool matching_cond(bool max_fl, TABLE_REF *ref, KEY *keyinfo, if (!cond) DBUG_RETURN(TRUE); Field *field= field_part->field; + if (cond->used_tables() & OUTER_REF_TABLE_BIT) + { + DBUG_RETURN(FALSE); + } if (!(cond->used_tables() & field->table->map) && test(cond->used_tables() & ~PSEUDO_TABLE_BITS)) { From 5ab628e0240ae280c0b5b03e1d64b2242cd7265e Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Wed, 28 Dec 2011 18:47:01 -0800 Subject: [PATCH 09/28] Fixed LP bug #777654. The method Item_sum_num::fix_fields() calculated the value of the flag Item_sum_num::maybe_null in some cases incorrectly. --- mysql-test/r/sum_distinct.result | 12 ++++++++++++ mysql-test/t/sum_distinct.test | 12 ++++++++++++ sql/item_sum.cc | 3 +-- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sum_distinct.result b/mysql-test/r/sum_distinct.result index c615817f52d..2746f5a09f4 100644 --- a/mysql-test/r/sum_distinct.result +++ b/mysql-test/r/sum_distinct.result @@ -95,3 +95,15 @@ SELECT SUM(DISTINCT id % 11) FROM t1; SUM(DISTINCT id % 11) 55 DROP TABLE t1; +# +# Bug #777654: empty subselect in FROM clause returning +# SUM(DISTINCT) over non-nullable field +# +CREATE TABLE t1 (a int NOT NULL) ; +SELECT SUM(DISTINCT a) FROM t1; +SUM(DISTINCT a) +NULL +SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t; +SUM(DISTINCT a) +NULL +DROP TABLE t1; diff --git a/mysql-test/t/sum_distinct.test b/mysql-test/t/sum_distinct.test index c58155a8e25..633a72fddc8 100644 --- a/mysql-test/t/sum_distinct.test +++ b/mysql-test/t/sum_distinct.test @@ -93,3 +93,15 @@ SELECT SUM(DISTINCT id) FROM t1; SELECT SUM(DISTINCT id % 11) FROM t1; DROP TABLE t1; + +--echo # +--echo # Bug #777654: empty subselect in FROM clause returning +--echo # SUM(DISTINCT) over non-nullable field +--echo # + +CREATE TABLE t1 (a int NOT NULL) ; + +SELECT SUM(DISTINCT a) FROM t1; +SELECT * FROM (SELECT SUM(DISTINCT a) FROM t1) AS t; + +DROP TABLE t1; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index ce7602b7f03..ac6ddc0fd54 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -568,13 +568,12 @@ Item_sum_num::fix_fields(THD *thd, Item **ref) return TRUE; decimals=0; - maybe_null=0; + maybe_null= sum_func() != COUNT_FUNC; for (uint i=0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1)) return TRUE; set_if_bigger(decimals, args[i]->decimals); - maybe_null |= args[i]->maybe_null; } result_field=0; max_length=float_length(decimals); From 40c42468bcbe215a971f93edb9af27545156b8a7 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 29 Dec 2011 15:09:20 -0800 Subject: [PATCH 10/28] Fixed LP bug #806057. A table expression with a natural join or a USING clause is transformed into an equivalent expression with equi-join ON conditions. If a reference to a virtual column happened to occur only in these generated equi-join conditions then it was not erroneously marked in the TABLE::vcol_set bitmap. This could lead to wrong results for queries containing natural join expressions or USING clauses. --- .../suite/vcol/r/vcol_select_myisam.result | 30 +++++++++++++++++++ .../suite/vcol/t/vcol_select_myisam.test | 20 +++++++++++++ sql/sql_base.cc | 7 ++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/vcol/r/vcol_select_myisam.result b/mysql-test/suite/vcol/r/vcol_select_myisam.result index 45e4defd315..04ae7e0f7cd 100644 --- a/mysql-test/suite/vcol/r/vcol_select_myisam.result +++ b/mysql-test/suite/vcol/r/vcol_select_myisam.result @@ -262,3 +262,33 @@ NULL explain select sum(c) from t1 group by b; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using temporary; Using filesort +# +# Bug #806057: join with USING over a virtual column +# +CREATE TABLE t1 (b int); +INSERT INTO t1 VALUES (NULL),( 78), (185), (0), (154); +CREATE TABLE t2 (a int, b int AS (a) VIRTUAL); +INSERT INTO t2 VALUES (187,187), (9,9), (187,187); +Warnings: +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +Warning 1647 The value specified for computed column 'b' in table 't2' ignored +EXPLAIN EXTENDED +SELECT * FROM t1 JOIN t2 USING (b); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`b` = `test`.`t2`.`b`) +SELECT * FROM t1 JOIN t2 USING (b); +b a +EXPLAIN EXTENDED +SELECT * FROM t1 NATURAL JOIN t2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` join `test`.`t2` where (`test`.`t1`.`b` = `test`.`t2`.`b`) +SELECT * FROM t1 NATURAL JOIN t2; +b a +DROP TABLE t1,t2; diff --git a/mysql-test/suite/vcol/t/vcol_select_myisam.test b/mysql-test/suite/vcol/t/vcol_select_myisam.test index 855e02ac113..c14faba576d 100644 --- a/mysql-test/suite/vcol/t/vcol_select_myisam.test +++ b/mysql-test/suite/vcol/t/vcol_select_myisam.test @@ -48,3 +48,23 @@ eval SET @@session.storage_engine = 'MyISAM'; #------------------------------------------------------------------------------# # Cleanup --source suite/vcol/inc/vcol_cleanup.inc + +--echo # +--echo # Bug #806057: join with USING over a virtual column +--echo # + +CREATE TABLE t1 (b int); +INSERT INTO t1 VALUES (NULL),( 78), (185), (0), (154); + +CREATE TABLE t2 (a int, b int AS (a) VIRTUAL); +INSERT INTO t2 VALUES (187,187), (9,9), (187,187); + +EXPLAIN EXTENDED +SELECT * FROM t1 JOIN t2 USING (b); +SELECT * FROM t1 JOIN t2 USING (b); + +EXPLAIN EXTENDED +SELECT * FROM t1 NATURAL JOIN t2; +SELECT * FROM t1 NATURAL JOIN t2; + +DROP TABLE t1,t2; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4616b5c2430..bd02bbca7ea 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7151,11 +7151,16 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2, if (!(eq_cond= new Item_func_eq(item_ident_1, item_ident_2))) goto err; /* Out of memory. */ + if (field_1 && field_1->vcol_info) + field_1->table->mark_virtual_col(field_1); + if (field_2 && field_2->vcol_info) + field_2->table->mark_virtual_col(field_2); + /* Add the new equi-join condition to the ON clause. Notice that fix_fields() is applied to all ON conditions in setup_conds() so we don't do it here. - */ + */ add_join_on((table_ref_1->outer_join & JOIN_TYPE_RIGHT ? table_ref_1 : table_ref_2), eq_cond); From 74fdbec68e81fb30a82ab5f9ff66b748d506f909 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Thu, 29 Dec 2011 21:55:17 -0800 Subject: [PATCH 11/28] Fixed LP bug #848652. The cause of this bug was the same as for bug 902356 fixed for 5.3. --- mysql-test/r/join_outer_innodb.result | 8 ++++++++ mysql-test/t/join_outer_innodb.test | 15 +++++++++++++++ sql/sql_select.cc | 7 ++++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/join_outer_innodb.result b/mysql-test/r/join_outer_innodb.result index e8a2d6f668b..c8bc9758408 100644 --- a/mysql-test/r/join_outer_innodb.result +++ b/mysql-test/r/join_outer_innodb.result @@ -17,3 +17,11 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where DROP TABLE t1,t2; +CREATE TABLE t1(a int, b int, KEY (a), PRIMARY KEY (b)) ENGINE=InnoDB; +CREATE TABLE t2 (b int, PRIMARY KEY (b)); +INSERT INTO t2 VALUES (4),(9); +SELECT STRAIGHT_JOIN t1.a FROM t1 RIGHT JOIN t2 ON t1.b = t2.b +WHERE (t1.b NOT BETWEEN 1 AND 7 OR t1.a IS NULL AND t1.b = t2.b) AND t2.b = 4 +GROUP BY 1; +a +DROP TABLE t1,t2; diff --git a/mysql-test/t/join_outer_innodb.test b/mysql-test/t/join_outer_innodb.test index 40add7f488f..565bb72b152 100644 --- a/mysql-test/t/join_outer_innodb.test +++ b/mysql-test/t/join_outer_innodb.test @@ -24,3 +24,18 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id WHERE t1.name LIKE 'A%' OR FALSE; DROP TABLE t1,t2; + +# +# Bug #848652: crash with RIGHT JOIN and GROUP BY +# + +CREATE TABLE t1(a int, b int, KEY (a), PRIMARY KEY (b)) ENGINE=InnoDB; + +CREATE TABLE t2 (b int, PRIMARY KEY (b)); +INSERT INTO t2 VALUES (4),(9); + +SELECT STRAIGHT_JOIN t1.a FROM t1 RIGHT JOIN t2 ON t1.b = t2.b + WHERE (t1.b NOT BETWEEN 1 AND 7 OR t1.a IS NULL AND t1.b = t2.b) AND t2.b = 4 +GROUP BY 1; + +DROP TABLE t1,t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8b7261a8712..5963a1c318a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13725,8 +13725,8 @@ find_field_in_item_list (Field *field, void *data) while ((item= li++)) { - if (item->type() == Item::FIELD_ITEM && - ((Item_field*) item)->field->eq(field)) + if (item->real_item()->type() == Item::FIELD_ITEM && + ((Item_field*) (item->real_item()))->field->eq(field)) { part_found= 1; break; @@ -13994,7 +13994,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, uint used_pk_parts= 0; if (used_key_parts > used_index_parts) used_pk_parts= used_key_parts-used_index_parts; - rec_per_key= keyinfo->rec_per_key[used_key_parts-1]; + rec_per_key= used_key_parts ? + keyinfo->rec_per_key[used_key_parts-1] : 1; /* Take into account the selectivity of the used pk prefix */ if (used_pk_parts) { From a0afa025a3f949efe0f414c2bf562139c4069f88 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 2 Jan 2012 23:52:31 +0100 Subject: [PATCH 12/28] Fix embedded/windows tests- move COND_manager and LOCK_manager to sql_manager.cc, to prevent race condition that results into accessing already destroyed critical section --- sql/mysql_priv.h | 4 ++-- sql/mysqld.cc | 4 ---- sql/sql_manager.cc | 12 ++++++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 065425c4c96..ed23ecb50fe 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2091,7 +2091,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open, LOCK_lock_db, LOCK_mapped_file,LOCK_user_locks, LOCK_status, LOCK_error_log, LOCK_delayed_insert, LOCK_short_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, - LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock, + LOCK_slave_list, LOCK_active_mi, LOCK_global_read_lock, LOCK_global_system_variables, LOCK_user_conn, LOCK_prepared_stmt_count, LOCK_bytes_sent, LOCK_bytes_received, LOCK_connection_count; @@ -2109,7 +2109,7 @@ extern pthread_mutex_t LOCK_stats; extern int mysqld_server_started; extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; extern rw_lock_t LOCK_system_variables_hash; -extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; +extern pthread_cond_t COND_refresh, COND_thread_count; extern pthread_cond_t COND_global_read_lock; extern pthread_attr_t connection_attrib; extern I_List threads; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0d0ad919515..aa27ea0f582 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1516,7 +1516,6 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_delayed_insert); (void) pthread_mutex_destroy(&LOCK_delayed_status); (void) pthread_mutex_destroy(&LOCK_delayed_create); - (void) pthread_mutex_destroy(&LOCK_manager); (void) pthread_mutex_destroy(&LOCK_crypt); (void) pthread_mutex_destroy(&LOCK_bytes_sent); (void) pthread_mutex_destroy(&LOCK_bytes_received); @@ -1557,7 +1556,6 @@ static void clean_up_mutexes() (void) pthread_cond_destroy(&COND_global_read_lock); (void) pthread_cond_destroy(&COND_thread_cache); (void) pthread_cond_destroy(&COND_flush_thread_cache); - (void) pthread_cond_destroy(&COND_manager); DBUG_VOID_RETURN; } @@ -3817,7 +3815,6 @@ static int init_thread_environment() (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST); @@ -3857,7 +3854,6 @@ static int init_thread_environment() (void) pthread_cond_init(&COND_global_read_lock,NULL); (void) pthread_cond_init(&COND_thread_cache,NULL); (void) pthread_cond_init(&COND_flush_thread_cache,NULL); - (void) pthread_cond_init(&COND_manager,NULL); #ifdef HAVE_REPLICATION (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST); (void) pthread_cond_init(&COND_rpl_status, NULL); diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index cf0a73d0ce7..57fe5072dcd 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -44,6 +44,7 @@ static struct handler_cb * volatile cb_list; bool mysql_manager_submit(void (*action)()) { bool result= FALSE; + DBUG_ASSERT(manager_thread_in_use); struct handler_cb * volatile *cb; pthread_mutex_lock(&LOCK_manager); cb= &cb_list; @@ -75,8 +76,9 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) pthread_detach_this_thread(); manager_thread = pthread_self(); + (void) pthread_cond_init(&COND_manager,NULL); + (void) pthread_mutex_init(&LOCK_manager,NULL); manager_thread_in_use = 1; - for (;;) { pthread_mutex_lock(&LOCK_manager); @@ -123,6 +125,8 @@ pthread_handler_t handle_manager(void *arg __attribute__((unused))) } } manager_thread_in_use = 0; + (void) pthread_mutex_destroy(&LOCK_manager); + (void) pthread_cond_destroy(&COND_manager); DBUG_LEAVE; // Can't use DBUG_RETURN after my_thread_end my_thread_end(); return (NULL); @@ -149,14 +153,14 @@ void stop_handle_manager() { DBUG_ENTER("stop_handle_manager"); abort_manager = true; - pthread_mutex_lock(&LOCK_manager); if (manager_thread_in_use) { + pthread_mutex_lock(&LOCK_manager); DBUG_PRINT("quit", ("initiate shutdown of handle manager thread: 0x%lx", (ulong)manager_thread)); - pthread_cond_signal(&COND_manager); + pthread_cond_signal(&COND_manager); + pthread_mutex_unlock(&LOCK_manager); } - pthread_mutex_unlock(&LOCK_manager); DBUG_VOID_RETURN; } From d63fc00f35e40315848133991ca6f336e3f87eb9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Jan 2012 11:06:52 +0200 Subject: [PATCH 13/28] Fix of LP BUG#793589 Wrong result with double ORDER BY Problem was in caching 'eq_ref' dependency between calls of remove_const() for ORDER BY and GROUP BY lists. --- mysql-test/r/order_by.result | 54 ++++++++++++++++++++++++++++++++++++ mysql-test/t/order_by.test | 29 +++++++++++++++++++ sql/sql_select.cc | 9 ++++++ 3 files changed, 92 insertions(+) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 0c522aef290..88d4e729c1f 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -1672,3 +1672,57 @@ select 1 order by max(1) + min(1); 1 1 End of 5.1 tests +# +# Fix of LP BUG#793589 Wrong result with double ORDER BY +# +CREATE TABLE t1 ( b int) ; +INSERT INTO t1 VALUES (8),(9); +CREATE TABLE t2 ( a int, b int, PRIMARY KEY (a)) ; +INSERT INTO t2 VALUES (6,7),(7,7),(8,1),(9,7),(10,1),(11,5),(12,2),(13,0),(14,1),(15,8),(16,1),(17,1),(18,9),(19,1),(20,5); +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +field1 +1 +7 +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +b b +1 8 +7 9 +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +b b +1 8 +7 9 +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +b +1 +7 +# field1 removed from ORDER BY +explain extended +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `field1` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +explain extended +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +explain extended +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +explain extended +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using temporary; Using filesort +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 100.00 +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where (`test`.`t2`.`a` = `test`.`t1`.`b`) group by `test`.`t2`.`b` order by `test`.`t1`.`b` +drop table t1,t2; +End of 5.2 tests diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 2a5f74a3a13..add256a7451 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -1518,3 +1518,32 @@ DROP TABLE t1; select 1 order by max(1) + min(1); --echo End of 5.1 tests + +--echo # +--echo # Fix of LP BUG#793589 Wrong result with double ORDER BY +--echo # +CREATE TABLE t1 ( b int) ; +INSERT INTO t1 VALUES (8),(9); + +CREATE TABLE t2 ( a int, b int, PRIMARY KEY (a)) ; +INSERT INTO t2 VALUES (6,7),(7,7),(8,1),(9,7),(10,1),(11,5),(12,2),(13,0),(14,1),(15,8),(16,1),(17,1),(18,9),(19,1),(20,5); + +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; + +--echo # field1 removed from ORDER BY +explain extended +SELECT t2.b AS field1 FROM t1, t2 WHERE t1.b = t2.a GROUP BY field1 ORDER BY t1.b, field1; +explain extended +SELECT t2.b, t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b, t2.b; +explain extended +SELECT t2.b,t1.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; +explain extended +SELECT t2.b FROM t1, t2 WHERE t1.b = t2.a GROUP BY t2.b ORDER BY t1.b; + + +drop table t1,t2; + +--echo End of 5.2 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b066ad1544d..3af05c3015a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7368,6 +7368,15 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, table_map ref; DBUG_ENTER("remove_const"); + /* + Cleanup to avoid interference of calls of this function for + ORDER BY and GROUP BY + */ + for (JOIN_TAB *tab= join->join_tab + join->const_tables; + tab < join->join_tab + join->tables; + tab++) + tab->cached_eq_ref_table= FALSE; + prev_ptr= &first_order; *simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1; From d725c52d27cb206bb0dc17c629535655a11885c2 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 7 Jan 2012 10:23:46 +0200 Subject: [PATCH 14/28] Fixed wrong merge --- sql/sql_parse.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8aed1229f5b..1510ea7bf10 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -190,7 +190,6 @@ bool end_active_trans(THD *thd) if (ha_commit(thd)) error=1; #ifdef WITH_ARIA_STORAGE_ENGINE - ha_maria::implicit_commit(thd, TRUE); if (ha_storage_engine_is_enabled(maria_hton)) ha_maria::implicit_commit(thd, TRUE); #endif @@ -1664,7 +1663,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->transaction.stmt.reset(); #ifdef WITH_ARIA_STORAGE_ENGINE - ha_maria::implicit_commit(thd, FALSE); if (ha_storage_engine_is_enabled(maria_hton)) ha_maria::implicit_commit(thd, FALSE); #endif From 629cdab80827e7ad6bb23f7c8dc20724eb87f4d9 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sun, 8 Jan 2012 20:29:05 +0200 Subject: [PATCH 15/28] Fixed compiler and test failures found by buildbot configure.in: Added testing of STRNDUP (not found on solaris) mysql-test/include/wait_until_connected_again.inc: Also test for error 2005 (can happen on windows) mysql-test/include/wait_until_disconnected.inc: Also test for error 2005 (can happen on windows) mysql-test/suite/innodb_plugin/r/innodb_bug30423.result: Number of rows is not stable (found difference on Solaris) mysql-test/suite/innodb_plugin/t/innodb_bug30423.test: Number of rows is not stable (found difference on Solaris) plugin/auth_pam/auth_pam.c: Use internal strndup if it doesn't exist on system (solaris) Changed code so that it should also compile on solaris. --- configure.in | 2 +- .../include/wait_until_connected_again.inc | 2 +- .../include/wait_until_disconnected.inc | 2 +- .../innodb_plugin/r/innodb_bug30423.result | 6 ++-- .../innodb_plugin/t/innodb_bug30423.test | 1 + plugin/auth_pam/auth_pam.c | 33 +++++++++++++++++-- 6 files changed, 37 insertions(+), 9 deletions(-) diff --git a/configure.in b/configure.in index a592fb76a0e..9c3cbd283dc 100644 --- a/configure.in +++ b/configure.in @@ -2033,7 +2033,7 @@ dnl Checks for library functions. AC_FUNC_ALLOCA AC_PROG_GCC_TRADITIONAL AC_TYPE_SIGNAL -AC_CHECK_FUNCS(re_comp regcomp strdup) +AC_CHECK_FUNCS(re_comp regcomp strdup strndup) dnl Sun compilers have their own vis.h that is about something dnl totally different. So, not to change the libedit source, we diff --git a/mysql-test/include/wait_until_connected_again.inc b/mysql-test/include/wait_until_connected_again.inc index aff92141a8b..96240e36db7 100644 --- a/mysql-test/include/wait_until_connected_again.inc +++ b/mysql-test/include/wait_until_connected_again.inc @@ -14,7 +14,7 @@ while ($mysql_errno) # Strangely enough, the server might return "Too many connections" # while being shutdown, thus 1040 is an "allowed" error # See BUG#36228 - --error 0,1040,1053,2002,2003,2006,2013 + --error 0,1040,1053,2002,2003,2005,2006,2013 show status; dec $counter; diff --git a/mysql-test/include/wait_until_disconnected.inc b/mysql-test/include/wait_until_disconnected.inc index c274fbbe089..71361682442 100644 --- a/mysql-test/include/wait_until_disconnected.inc +++ b/mysql-test/include/wait_until_disconnected.inc @@ -12,7 +12,7 @@ while (!$mysql_errno) # Strangely enough, the server might return "Too many connections" # while being shutdown, thus 1040 is an "allowed" error. # See BUG#36228. - --error 0,1040,1053,2002,2003,2006,2013 + --error 0,1040,1053,2002,2003,2005,2006,2013 show status; dec $counter; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug30423.result b/mysql-test/suite/innodb_plugin/r/innodb_bug30423.result index a19809366ae..6071587e888 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_bug30423.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug30423.result @@ -48,9 +48,9 @@ ON orgs.org_id=sa_opportunities.org_id LEFT JOIN bug30243_2 contacts ON orgs.org_id=contacts.org_id ; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE orgs index NULL org_id 4 NULL 128 Using index -1 SIMPLE sa_opportunities ref org_id org_id 5 test.orgs.org_id 1 Using index -1 SIMPLE contacts ref contacts$org_id contacts$org_id 5 test.orgs.org_id 1 Using index +1 SIMPLE orgs index NULL org_id 4 NULL # Using index +1 SIMPLE sa_opportunities ref org_id org_id 5 test.orgs.org_id # Using index +1 SIMPLE contacts ref contacts$org_id contacts$org_id 5 test.orgs.org_id # Using index select @@innodb_stats_method; @@innodb_stats_method nulls_ignored diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug30423.test b/mysql-test/suite/innodb_plugin/t/innodb_bug30423.test index 458c2967e19..da490589400 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug30423.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug30423.test @@ -140,6 +140,7 @@ analyze table bug30243_3; # Following query plan shows that we get the correct rows per # unique value (should be approximately 1 row per value) +--replace_column 9 # explain SELECT COUNT(*), 0 FROM bug30243_1 orgs LEFT JOIN bug30243_3 sa_opportunities diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index 45c49975f6e..0d9cf2ae0af 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -8,6 +9,24 @@ struct param { MYSQL_PLUGIN_VIO *vio; }; +/* It least solaris doesn't have strndup */ + +#ifndef HAVE_STRNDUP +char *strndup(const char *from, size_t length) +{ + char *ptr; + size_t max_length= strlen(from); + if (length > max_length) + length= max_length; + if ((ptr= (char*) malloc(length+1)) != 0) + { + memcpy((char*) ptr, (char*) from, length); + ptr[length]=0; + } + return ptr; +} +#endif + static int conv(int n, const struct pam_message **msg, struct pam_response **resp, void *data) { @@ -71,13 +90,21 @@ static int conv(int n, const struct pam_message **msg, #define DO(X) if ((status = (X)) != PAM_SUCCESS) goto end +#ifdef SOLARIS +typedef void** pam_get_item_3_arg; +#else +typedef const void** pam_get_item_3_arg; +#endif + static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) { pam_handle_t *pamh = NULL; int status; const char *new_username; struct param param; - struct pam_conv c = { &conv, ¶m }; + /* The following is written in such a way to make also solaris happy */ + struct pam_conv pam_start_arg = { &conv, NULL }; + pam_start_arg.appdata_ptr= (char*) ¶m; /* get the service name, as specified in @@ -90,10 +117,10 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) param.ptr = param.buf + 1; param.vio = vio; - DO( pam_start(service, info->user_name, &c, &pamh) ); + DO( pam_start(service, info->user_name, &pam_start_arg, &pamh) ); DO( pam_authenticate (pamh, 0) ); DO( pam_acct_mgmt(pamh, 0) ); - DO( pam_get_item(pamh, PAM_USER, (const void**)&new_username) ); + DO( pam_get_item(pamh, PAM_USER, (pam_get_item_3_arg) &new_username) ); if (new_username && strcmp(new_username, info->user_name)) strncpy(info->authenticated_as, new_username, From 39ebfa51ef1dbb2807ea46063e6a5936103ffb01 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 10 Jan 2012 19:23:00 +0100 Subject: [PATCH 16/28] Fix MDEV-49 : version_compile_machine server variable is 'unknown' for x64 builds --- include/config-win.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/config-win.h b/include/config-win.h index 9369c72e83d..86fcc61aa9b 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -45,8 +45,8 @@ #define MACHINE_TYPE "ia64" #elif defined(_M_IX86) #define MACHINE_TYPE "ia32" -#elif defined(_M_ALPHA) -#define MACHINE_TYPE "axp" +#elif defined(_M_X64) +#define MACHINE_TYPE "x64" #else #define MACHINE_TYPE "unknown" /* Define to machine type name */ #endif From 22876a5495b5ddb9a310a56953a1b572946712c1 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Tue, 10 Jan 2012 19:26:47 +0100 Subject: [PATCH 17/28] MDEV-50 : Fix default compilation comment --- win/cmake/mysql_version.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/cmake/mysql_version.cmake b/win/cmake/mysql_version.cmake index 79e6a18ee1d..e6b64d3003e 100644 --- a/win/cmake/mysql_version.cmake +++ b/win/cmake/mysql_version.cmake @@ -81,7 +81,7 @@ IF(NOT MYSQL_UNIX_ADDR) SET(MYSQL_UNIX_ADDR "/tmp/mysql.sock") ENDIF() IF(NOT COMPILATION_COMMENT) - SET(COMPILATION_COMMENT "Source distribution") + SET(COMPILATION_COMMENT "mariadb.org binary distribution") ENDIF() From 6dfe0956d64b41a2e4eda0f40feaad799cd84058 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 13 Jan 2012 12:23:19 -0800 Subject: [PATCH 18/28] Back-ported the test cases for bug #12763207 from mysql-5.6 code line into 5.2 Completed the fix for this bug. Note: in 5.3 the affected 'if' statement in Item_in_subselect::single_value_transformer() starting with the condition (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) should be removed altogether. The change from table.cc is not needed either. This is because in 5.3 - min/max transformation for subqueries are done at the optimization phase - evaluation of the expensive subqueries is done at the execution phase. Added an EXPLAIN EXTENDED to the test case for bug #12329653. --- mysql-test/r/subselect.result | 53 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 53 +++++++++++++++++++++++++++++++++++ sql/item_subselect.cc | 3 +- sql/table.cc | 1 + 4 files changed, 109 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 65e76d04c1f..5063b4c6db9 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4568,6 +4568,13 @@ CREATE TABLE t1(a1 int); INSERT INTO t1 VALUES (1),(2); SELECT @@session.sql_mode INTO @old_sql_mode; SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 SUBQUERY t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 select 1 AS `1` from `test`.`t1` where 1 SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); 1 1 @@ -5088,4 +5095,50 @@ NULL NULL 5 DROP TABLE t1, t2, t3; +# +# Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +# +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +1 +1 +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +1 +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); +1 +1 +1 +SET SESSION sql_mode=@old_sql_mode; +DROP TABLE t1, t2; +create table t2(i int); +insert into t2 values(0); +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; +CREATE TABLE t1 ( +pk int NOT NULL, +col_varchar_key varchar(1) DEFAULT NULL, +PRIMARY KEY (pk), +KEY col_varchar_key (col_varchar_key) +); +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; +pk +SET SESSION sql_mode=@old_sql_mode; +drop table t2, t1; +drop view v1; End of 5.2 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index b918e800dd5..e4ed6188f25 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3460,6 +3460,8 @@ SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; ## First a simpler query, illustrating the transformation ## '1 < some (...)' => '1 < max(...)' +EXPLAIN EXTENDED +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t1); ## The query which made the server crash. @@ -3958,4 +3960,55 @@ INSERT INTO t3 VALUES (0),(0); SELECT a1.f3 AS r FROM t2 AS a1 , t1 WHERE a1.f3 < ALL ( SELECT f3 FROM t3 WHERE f3 = 1 ) ; DROP TABLE t1, t2, t3; +--echo # +--echo # Bug#12763207 - ASSERT IN SUBSELECT::SINGLE_VALUE_TRANSFORMER +--echo # + +CREATE TABLE t1(a1 int); +INSERT INTO t1 VALUES (1),(2); + +CREATE TABLE t2(a1 int); +INSERT INTO t2 VALUES (3); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +## All these are subject to the transformation +## '1 < some (...)' => '1 < max(...)' +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 2.0 FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT 'a' FROM t2); +SELECT 1 FROM t1 WHERE 1 < SOME (SELECT a1 FROM t2); + +SET SESSION sql_mode=@old_sql_mode; + +DROP TABLE t1, t2; + +create table t2(i int); +insert into t2 values(0); + +SELECT @@session.sql_mode INTO @old_sql_mode; +SET SESSION sql_mode='ONLY_FULL_GROUP_BY'; + +CREATE VIEW v1 AS +SELECT 'f' FROM t2 UNION SELECT 'x' FROM t2 +; + +CREATE TABLE t1 ( + pk int NOT NULL, + col_varchar_key varchar(1) DEFAULT NULL, + PRIMARY KEY (pk), + KEY col_varchar_key (col_varchar_key) +); + +SELECT t1.pk +FROM t1 +WHERE t1.col_varchar_key < ALL ( SELECT * FROM v1 ) +; + +SET SESSION sql_mode=@old_sql_mode; + +drop table t2, t1; +drop view v1; + --echo End of 5.2 tests diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 82d2313aa2b..2828ae8c4ec 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1057,7 +1057,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, print_where(item, "rewrite with MIN/MAX", QT_ORDINARY);); if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) { - DBUG_ASSERT(select_lex->non_agg_field_used()); + DBUG_ASSERT(item->get_arg(0)->real_item()->type() != Item::FIELD_ITEM || + select_lex->non_agg_field_used()); select_lex->set_non_agg_field_used(false); } diff --git a/sql/table.cc b/sql/table.cc index ca14b2ef4d2..a3df9023805 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4467,6 +4467,7 @@ Item *Field_iterator_table::create_item(THD *thd) { select->non_agg_fields.push_back(item); item->marker= select->cur_pos_in_select_list; + select->set_non_agg_field_used(true); } return item; } From 4de7978a3f3e716a6b1b280ce1f30dd501e31545 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 13 Jan 2012 19:00:50 -0800 Subject: [PATCH 19/28] Back-ported the fix and the test case for bug #50257 from mariadb-5.3 code line. Adjusted results for a few test cases. --- mysql-test/r/index_merge_myisam.result | 2 +- mysql-test/r/subselect.result | 20 ++++++++++++++++--- mysql-test/suite/innodb/r/innodb_mysql.result | 6 +++--- .../suite/innodb_plugin/r/innodb_mysql.result | 6 +++--- mysql-test/suite/pbxt/r/subselect.result | 4 ++-- mysql-test/t/subselect.test | 15 ++++++++++++-- sql/sql_select.cc | 3 +-- 7 files changed, 40 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/index_merge_myisam.result b/mysql-test/r/index_merge_myisam.result index df570e1f4ae..ad44f241f5c 100644 --- a/mysql-test/r/index_merge_myisam.result +++ b/mysql-test/r/index_merge_myisam.result @@ -1486,7 +1486,7 @@ EXPLAIN SELECT t1.f1 FROM t1 WHERE (SELECT COUNT(*) FROM t2 WHERE t2.f3 = 'h' AND t2.f2 = t1.f1) = 0 AND t1.f1 = 2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 -2 DEPENDENT SUBQUERY t2 ref f2,f3 f2 5 1 Using where +2 DEPENDENT SUBQUERY t2 ref f2,f3 f2 5 const 1 Using where DROP TABLE t1,t2; # # Generic @@optimizer_switch tests (move those into a separate file if diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 5063b4c6db9..f1e65f0fb1f 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -363,9 +363,9 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1'); EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index -4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index +4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index 2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 -3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index +3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index Warnings: Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM @@ -4780,7 +4780,6 @@ EXPLAIN EXTENDED SELECT DISTINCT 1 FROM t1, WHERE t1.a = d1.a; ERROR 42S22: Unknown column 'd1.a' in 'where clause' DROP TABLE t1; -End of 5.1 tests. Set up test tables. CREATE TABLE t1 ( t1_id INT UNSIGNED, @@ -5141,4 +5140,19 @@ pk SET SESSION sql_mode=@old_sql_mode; drop table t2, t1; drop view v1; +# +# BUG#50257: Missing info in REF column of the EXPLAIN +# lines for subselects +# +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY system NULL NULL NULL NULL 1 +2 DERIVED t1 ref a a 5 const 1 Using where +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +2 SUBQUERY t1 ref a a 5 const 1 Using where; Using index +DROP TABLE t1; End of 5.2 tests diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 666d6b7591f..e022bd961d6 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -1739,7 +1739,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 5 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 5 const 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) ENGINE=InnoDB; @@ -1753,7 +1753,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 9 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 9 const 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), KEY (c3), KEY (c2, c3)) @@ -1768,7 +1768,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 7 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 7 const 5 Using where; Using filesort DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index 987a04eb59d..49e8b44b018 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -1739,7 +1739,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 5 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 5 const 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3)) ENGINE=InnoDB; @@ -1753,7 +1753,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 9 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 9 const 5 Using where; Using filesort DROP TABLE t1; CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2), KEY (c3), KEY (c2, c3)) @@ -1768,7 +1768,7 @@ SELECT 1 FROM (SELECT COUNT(DISTINCT c1) FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY system NULL NULL NULL NULL 1 -2 DERIVED t1 ALL c3,c2 c3 7 5 Using where; Using filesort +2 DERIVED t1 ALL c3,c2 c3 7 const 5 Using where; Using filesort DROP TABLE t1; End of 5.1 tests drop table if exists t1, t2, t3; diff --git a/mysql-test/suite/pbxt/r/subselect.result b/mysql-test/suite/pbxt/r/subselect.result index 63b289d259e..0b5c98324f4 100644 --- a/mysql-test/suite/pbxt/r/subselect.result +++ b/mysql-test/suite/pbxt/r/subselect.result @@ -363,9 +363,9 @@ INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1'); EXPLAIN EXTENDED SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index -4 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index +4 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index 2 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 -3 SUBQUERY t8 const PRIMARY PRIMARY 37 1 100.00 Using index +3 SUBQUERY t8 const PRIMARY PRIMARY 37 const 1 100.00 Using index Warnings: Note 1003 select 'joce' AS `pseudo`,(select 'test' from `test`.`t8` where 1) AS `(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'))` from `test`.`t8` where 1 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index e4ed6188f25..1f3c102770c 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3710,8 +3710,6 @@ WHERE t1.a = d1.a; DROP TABLE t1; ---echo End of 5.1 tests. - # # Bug #47904 Incorrect results w/ table subquery, derived SQs, and LEFT JOIN on index # @@ -4011,4 +4009,17 @@ SET SESSION sql_mode=@old_sql_mode; drop table t2, t1; drop view v1; +--echo # +--echo # BUG#50257: Missing info in REF column of the EXPLAIN +--echo # lines for subselects +--echo # + +CREATE TABLE t1 (a INT, b INT, INDEX (a)); +INSERT INTO t1 VALUES (3, 10), (2, 20), (7, 10), (5, 20); + +EXPLAIN SELECT * FROM (SELECT * FROM t1 WHERE a=7) t; +EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); + +DROP TABLE t1; + --echo End of 5.2 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3af05c3015a..3cf0800a62f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5913,8 +5913,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, if (keyuse->null_rejecting) j->ref.null_rejecting |= 1 << i; keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; - if (!keyuse->used_tables && - !(join->select_options & SELECT_DESCRIBE)) + if (!keyuse->used_tables &&!thd->lex->describe) { // Compare against constant store_key_item tmp(thd, keyinfo->key_part[i].field, key_buff + maybe_null, From 4b7919368ebd14ec09eef1e8508ebbab71b86e0c Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sat, 14 Jan 2012 00:02:02 -0800 Subject: [PATCH 20/28] Back-ported the test case for bug #12616253 from mariadb-5.3 that was actually a duplicate of LP bug #888456 fixed in mariadb-5.2. --- mysql-test/r/subselect.result | 41 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 21 ++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index f1e65f0fb1f..101869e2843 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -5155,4 +5155,45 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 2 SUBQUERY t1 ref a a 5 const 1 Using where; Using index DROP TABLE t1; +# +# BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +# (duplicate of LP bug #888456) +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY table1 ALL NULL NULL NULL NULL 2 +1 PRIMARY table2 index NULL f1_key 4 NULL 10 Using where; Using index; Using join buffer +2 DEPENDENT SUBQUERY t2 index f1_key f1_key 4 NULL 10 Using where; Using index; Using temporary +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 +WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 +WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +f1 f1_key +v j +s j +v v +s v +v c +s c +v m +s m +v d +s d +v d +s d +v y +s y +v t +s t +v d +s d +v s +s s +DROP TABLE t1,t2; End of 5.2 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1f3c102770c..24aad3a145d 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -4022,4 +4022,25 @@ EXPLAIN SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t1 WHERE a=7); DROP TABLE t1; +--echo # +--echo # BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) +--echo # (duplicate of LP bug #888456) + +CREATE TABLE t1 (f1 varchar(1)); +INSERT INTO t1 VALUES ('v'),('s'); + +CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); +INSERT INTO t2 VALUES ('j'),('v'),('c'),('m'),('d'), +('d'),('y'),('t'),('d'),('s'); + +EXPLAIN +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 + WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 + WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); +SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 + WHERE EXISTS (SELECT DISTINCT f1_key FROM t2 + WHERE f1_key != table2.f1_key AND f1_key >= table1.f1); + +DROP TABLE t1,t2; + --echo End of 5.2 tests From 1417606b1f4c5f8a4c24f6a93a77586f9cf5975c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 29 Dec 2011 22:52:13 +0100 Subject: [PATCH 21/28] on windows: don't link all plugins with mysqld, only do it for storage engines. --- storage/mysql_storage_engine.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/storage/mysql_storage_engine.cmake b/storage/mysql_storage_engine.cmake index cbe9a310d67..cc3659d51c9 100644 --- a/storage/mysql_storage_engine.cmake +++ b/storage/mysql_storage_engine.cmake @@ -42,7 +42,7 @@ IF(NOT SOURCE_SUBLIBS) ADD_DEFINITIONS(-DMYSQL_DYNAMIC_PLUGIN) ADD_VERSION_INFO(${${engine}_LIB} SHARED ${engine}_SOURCES) ADD_LIBRARY(${${engine}_LIB} MODULE ${${engine}_SOURCES}) - TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqlservices mysqld) + TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqlservices) IF(${engine}_LIBS) TARGET_LINK_LIBRARIES(${${engine}_LIB} ${${engine}_LIBS}) ENDIF(${engine}_LIBS) @@ -61,6 +61,8 @@ IF(NOT SOURCE_SUBLIBS) ${CMAKE_SOURCE_DIR}/extra/yassl/include) IF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC") ADD_DEFINITIONS(-DWITH_${engine}_STORAGE_ENGINE -DMYSQL_SERVER) + ELSEIF(${ENGINE_BUILD_TYPE} STREQUAL "DYNAMIC") + TARGET_LINK_LIBRARIES (${${engine}_LIB} mysqld) ENDIF(${ENGINE_BUILD_TYPE} STREQUAL "STATIC") ENDIF(NOT SOURCE_SUBLIBS) ENDMACRO(MYSQL_STORAGE_ENGINE) From b8b7b4eb6bef26d05257272be02674ae5514ded9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 30 Dec 2011 13:57:03 +0100 Subject: [PATCH 22/28] plugin renamed socket_peercred -> unix_socket. test added. --- mysql-test/suite/plugins/r/unix_socket.result | 30 ++++++++++ mysql-test/suite/plugins/t/unix_socket.test | 56 +++++++++++++++++++ plugin/auth/auth_socket.c | 18 +----- 3 files changed, 87 insertions(+), 17 deletions(-) create mode 100644 mysql-test/suite/plugins/r/unix_socket.result create mode 100644 mysql-test/suite/plugins/t/unix_socket.test diff --git a/mysql-test/suite/plugins/r/unix_socket.result b/mysql-test/suite/plugins/r/unix_socket.result new file mode 100644 index 00000000000..45bf608cc93 --- /dev/null +++ b/mysql-test/suite/plugins/r/unix_socket.result @@ -0,0 +1,30 @@ +install plugin unix_socket soname 'auth_socket.so'; +# +# with named user +# +create user USER identified via unix_socket; +# +# name match = ok +# +select user(), current_user(), database(); +user() current_user() database() +USER@localhost USER@% test +# +# name does not match = failure +# +drop user USER; +# +# and now with anonymous user +# +grant SELECT ON test.* TO '' identified via unix_socket; +# +# name match = ok +# +select user(), current_user(), database(); +user() current_user() database() +USER@localhost @% test +# +# name does not match = failure +# +delete from mysql.user where user=''; +uninstall plugin unix_socket; diff --git a/mysql-test/suite/plugins/t/unix_socket.test b/mysql-test/suite/plugins/t/unix_socket.test new file mode 100644 index 00000000000..fc2e6c5b3c6 --- /dev/null +++ b/mysql-test/suite/plugins/t/unix_socket.test @@ -0,0 +1,56 @@ +--source include/not_embedded.inc + +if (!$AUTH_SOCKET_SO) { + skip No auth_socket plugin; +} + +let $plugindir=`SELECT @@global.plugin_dir`; + +eval install plugin unix_socket soname '$AUTH_SOCKET_SO'; + +--echo # +--echo # with named user +--echo # + +--replace_result $USER USER +eval create user $USER identified via unix_socket; + +--write_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt +--replace_result $USER USER +select user(), current_user(), database(); +EOF + +--echo # +--echo # name match = ok +--echo # +--exec $MYSQL_TEST -u $USER --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +--echo # +--echo # name does not match = failure +--echo # +--error 1 +--exec $MYSQL_TEST -u foobar --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +--replace_result $USER USER +eval drop user $USER; + +--echo # +--echo # and now with anonymous user +--echo # +grant SELECT ON test.* TO '' identified via unix_socket; +--echo # +--echo # name match = ok +--echo # +--exec $MYSQL_TEST -u $USER --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +--echo # +--echo # name does not match = failure +--echo # +--error 1 +--exec $MYSQL_TEST -u foobar --plugin-dir=$plugindir < $MYSQLTEST_VARDIR/tmp/peercred_test.txt + +# restoring mysql.user to the original state. +delete from mysql.user where user=''; +uninstall plugin unix_socket; +--remove_file $MYSQLTEST_VARDIR/tmp/peercred_test.txt + diff --git a/plugin/auth/auth_socket.c b/plugin/auth/auth_socket.c index cc406dac331..89d24e46f3c 100644 --- a/plugin/auth/auth_socket.c +++ b/plugin/auth/auth_socket.c @@ -83,27 +83,11 @@ static struct st_mysql_auth socket_auth_handler= socket_auth }; -mysql_declare_plugin(socket_auth) -{ - MYSQL_AUTHENTICATION_PLUGIN, - &socket_auth_handler, - "socket_peercred", - "Sergei Golubchik", - "Unix Socket based authentication", - PLUGIN_LICENSE_GPL, - NULL, - NULL, - 0x0100, - NULL, - NULL, - NULL -} -mysql_declare_plugin_end; maria_declare_plugin(socket_auth) { MYSQL_AUTHENTICATION_PLUGIN, &socket_auth_handler, - "socket_peercred", + "unix_socket", "Sergei Golubchik", "Unix Socket based authentication", PLUGIN_LICENSE_GPL, From 3c1125d4cafdf352ea84d2ff8e06738c4aec2156 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jan 2012 20:12:14 +0100 Subject: [PATCH 23/28] fixes for get_password(): 1. on windows: don't hang when there's no console, that is, _getch() returns -1. 2. on windows: _getch() returns an int, not char. to distinguish between (char)255 and (int)-1 3. everywhere. isspace(pos[-1]) == ' ' never worked, isspace() returns a boolean, not a char. the never-worked loop was removed to preserve the existing behavior. --- libmysql/get_password.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libmysql/get_password.c b/libmysql/get_password.c index 747d598d72a..21200acf512 100644 --- a/libmysql/get_password.c +++ b/libmysql/get_password.c @@ -82,9 +82,9 @@ void get_tty_password_buff(const char *opt_message, char *to, size_t length) _cputs(opt_message ? opt_message : "Enter password: "); for (;;) { - char tmp; + int tmp; tmp=_getch(); - if (tmp == '\b' || (int) tmp == 127) + if (tmp == '\b' || tmp == 127) { if (pos != to) { @@ -93,15 +93,13 @@ void get_tty_password_buff(const char *opt_message, char *to, size_t length) continue; } } - if (tmp == '\n' || tmp == '\r' || tmp == 3) + if (tmp == -1 || tmp == '\n' || tmp == '\r' || tmp == 3) break; if (iscntrl(tmp) || pos == end) continue; _cputs("*"); - *(pos++) = tmp; + *(pos++) = (char)tmp; } - while (pos != to && isspace(pos[-1]) == ' ') - pos--; /* Allow dummy space at end */ *pos=0; _cputs("\n"); } @@ -148,8 +146,6 @@ static void get_password(char *to,uint length,int fd, my_bool echo) } *(pos++) = tmp; } - while (pos != to && isspace(pos[-1]) == ' ') - pos--; /* Allow dummy space at end */ *pos=0; return; } From f523df0a04b5c43103d9628f8c714b81b735e838 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jan 2012 20:12:46 +0100 Subject: [PATCH 24/28] openpam compatibility --- plugin/auth_pam/auth_pam.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index 0d9cf2ae0af..ee13b37f793 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -131,7 +131,7 @@ end: return status == PAM_SUCCESS ? CR_OK : CR_ERROR; } -static struct st_mysql_auth pam_info = +static struct st_mysql_auth info = { MYSQL_AUTHENTICATION_INTERFACE_VERSION, "dialog", @@ -141,7 +141,7 @@ static struct st_mysql_auth pam_info = maria_declare_plugin(pam) { MYSQL_AUTHENTICATION_PLUGIN, - &pam_info, + &info, "pam", "Sergei Golubchik", "PAM based authentication", From a1e3fa93c74d50de3160545d3d9c18ca06dfcc7e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jan 2012 20:13:22 +0100 Subject: [PATCH 25/28] lp:893522 more problems found by PVS Studio --- sql/scheduler.cc | 2 +- sql/winservice.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/scheduler.cc b/sql/scheduler.cc index 6dd93640dc5..d301b205b58 100644 --- a/sql/scheduler.cc +++ b/sql/scheduler.cc @@ -514,7 +514,7 @@ static void libevent_connection_close(THD *thd) thd->killed= THD::KILL_CONNECTION; // Avoid error messages - if (thd->net.vio->sd >= 0) // not already closed + if (thd->net.vio->type != VIO_CLOSED) // not already closed { end_connection(thd); close_connection(thd, 0, 1); diff --git a/sql/winservice.c b/sql/winservice.c index 562f047fa79..3ec91c26835 100644 --- a/sql/winservice.c +++ b/sql/winservice.c @@ -116,7 +116,7 @@ int get_mysql_service_properties(const wchar_t *bin_path, wcscat(mysqld_path, L".exe"); if(wcsicmp(file_part, L"mysqld.exe") != 0 && - wcsicmp(file_part, L"mysqld.exe") != 0 && + wcsicmp(file_part, L"mysqld-debug.exe") != 0 && wcsicmp(file_part, L"mysqld-nt.exe") != 0) { /* The service executable is not mysqld. */ @@ -244,4 +244,4 @@ int get_mysql_service_properties(const wchar_t *bin_path, end: LocalFree((HLOCAL)args); return retval; -} \ No newline at end of file +} From e4c61d263bd452200440f38284294170246c73b0 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jan 2012 20:13:41 +0100 Subject: [PATCH 26/28] lp:901693 dialog.c:perform_dialog treats every password prompt as first --- plugin/auth/dialog.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugin/auth/dialog.c b/plugin/auth/dialog.c index 24765c17d1c..6b54096f8ea 100644 --- a/plugin/auth/dialog.c +++ b/plugin/auth/dialog.c @@ -290,6 +290,8 @@ static int perform_dialog(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) if (res) return CR_ERROR; + first= 0; + /* repeat unless it was the last question */ } while ((cmd & 1) != 1); From bb4053afc3cb30c6016530884061d520350004f1 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Fri, 20 Jan 2012 23:54:43 -0800 Subject: [PATCH 27/28] Fixed LP bug #919427. The function subselect_uniquesubquery_engine::copy_ref_key has to take into account that when EXPLAIN is processed the array of store_key object created for any TABLE_REF may contain elements for constant items. These items should be ignored by thefunction. --- mysql-test/r/subselect.result | 49 +++++++++++++++++++++++++++++++++++ mysql-test/t/subselect.test | 46 ++++++++++++++++++++++++++++++++ sql/item_subselect.cc | 2 ++ sql/sql_select.h | 2 ++ 4 files changed, 99 insertions(+) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 101869e2843..4e12294da79 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -5158,6 +5158,7 @@ DROP TABLE t1; # # BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) # (duplicate of LP bug #888456) +# CREATE TABLE t1 (f1 varchar(1)); INSERT INTO t1 VALUES ('v'),('s'); CREATE TABLE t2 (f1_key varchar(1), KEY (f1_key)); @@ -5196,4 +5197,52 @@ s d v s s s DROP TABLE t1,t2; +# +# LP bug 919427: EXPLAIN for a query over a single-row table +# with IN subquery in WHERE condition +# +CREATE TABLE ot ( +col_int_nokey int(11), +col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); +CREATE TABLE it1( +col_int_key int(11), +col_varchar_key varchar(1), +KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); +CREATE TABLE it2 ( +col_int_key int(11), +col_varchar_key varchar(1), +col_varchar_key2 varchar(1), +KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), +KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY it1 index_subquery idx_cvk_cik idx_cvk_cik 9 func,const 2 Using index; Using where +SELECT col_int_nokey FROM ot +WHERE col_varchar_nokey IN +(SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +col_int_nokey +1 +EXPLAIN +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +2 DEPENDENT SUBQUERY it2 index_subquery idx_cvk_cvk2_cik,idx_cvk_cik idx_cvk_cvk2_cik 8 func,const 1 Using index; Using where +SELECT col_int_nokey FROM ot +WHERE (col_varchar_nokey, 'x') IN +(SELECT col_varchar_key, col_varchar_key2 FROM it2); +col_int_nokey +1 +DROP TABLE ot,it1,it2; End of 5.2 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 24aad3a145d..6bb9a9ae875 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -4025,6 +4025,7 @@ DROP TABLE t1; --echo # --echo # BUG#12616253 - WRONG RESULT WITH EXISTS(SUBQUERY) (MISSING ROWS) --echo # (duplicate of LP bug #888456) +--echo # CREATE TABLE t1 (f1 varchar(1)); INSERT INTO t1 VALUES ('v'),('s'); @@ -4043,4 +4044,49 @@ SELECT table1.f1, table2.f1_key FROM t1 AS table1, t2 AS table2 DROP TABLE t1,t2; +--echo # +--echo # LP bug 919427: EXPLAIN for a query over a single-row table +--echo # with IN subquery in WHERE condition +--echo # + +CREATE TABLE ot ( + col_int_nokey int(11), + col_varchar_nokey varchar(1) +) ; +INSERT INTO ot VALUES (1,'x'); + +CREATE TABLE it1( + col_int_key int(11), + col_varchar_key varchar(1), + KEY idx_cvk_cik (col_varchar_key,col_int_key) +); +INSERT INTO it1 VALUES (NULL,'x'), (NULL,'f'); + +CREATE TABLE it2 ( + col_int_key int(11), + col_varchar_key varchar(1), + col_varchar_key2 varchar(1), + KEY idx_cvk_cvk2_cik (col_varchar_key, col_varchar_key2, col_int_key), + KEY idx_cvk_cik (col_varchar_key, col_int_key) +); +INSERT INTO it2 VALUES (NULL,'x','x'), (NULL,'f','f'); + +EXPLAIN +SELECT col_int_nokey FROM ot + WHERE col_varchar_nokey IN + (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); +SELECT col_int_nokey FROM ot + WHERE col_varchar_nokey IN + (SELECT col_varchar_key FROM it1 WHERE col_int_key IS NULL); + +EXPLAIN +SELECT col_int_nokey FROM ot + WHERE (col_varchar_nokey, 'x') IN + (SELECT col_varchar_key, col_varchar_key2 FROM it2); +SELECT col_int_nokey FROM ot + WHERE (col_varchar_nokey, 'x') IN + (SELECT col_varchar_key, col_varchar_key2 FROM it2); + +DROP TABLE ot,it1,it2; + --echo End of 5.2 tests diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 2828ae8c4ec..3aa8dcd56f0 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2171,6 +2171,8 @@ bool subselect_uniquesubquery_engine::copy_ref_key() for (store_key **copy= tab->ref.key_copy ; *copy ; copy++) { + if ((*copy)->store_key_is_const()) + continue; tab->ref.key_err= (*copy)->copy(); /* diff --git a/sql/sql_select.h b/sql/sql_select.h index 1d1a023d9cf..79c07e80b25 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -670,6 +670,7 @@ public: } virtual ~store_key() {} /** Not actually needed */ virtual const char *name() const=0; + virtual bool store_key_is_const() { return false; } /** @brief sets ignore truncation warnings mode and calls the real copy method @@ -784,6 +785,7 @@ public: { } const char *name() const { return "const"; } + bool store_key_is_const() { return true; } protected: enum store_key_result copy_inner() From 81690cf326e09799ca77d9f7bc5601905b706548 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 23 Jan 2012 11:43:28 +0100 Subject: [PATCH 28/28] MDEV-106 my_gethwaddr() does not compile on Solaris 11 --- mysys/my_gethwaddr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index c96af3f1018..c4ab39dbcf1 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -101,14 +101,14 @@ my_bool my_gethwaddr(uchar *to) uint i; for (i= 0; res && i < ifc.ifc_len / sizeof(ifr[0]); i++) { -#ifdef SIOCGIFHWADDR +#ifdef __linux__ if (ioctl(fd, SIOCGIFHWADDR, &ifr[i]) >= 0) res= memcpy_and_test(to, (uchar *)&ifr[i].ifr_hwaddr.sa_data, ETHER_ADDR_LEN); #else /* - A bug in OpenSolaris prevents non-root from getting a mac address: - http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4720634 + A bug in OpenSolaris used to prevent non-root from getting a mac address: + {no url. Oracle killed the old OpenSolaris bug database} Thus, we'll use an alternative method and extract the address from the arp table.