diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 836efa2980c..603ae372f75 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5359,6 +5359,21 @@ a 2 DROP TABLE t11, t12| DROP FUNCTION bug19862| +drop table if exists t3| +drop database if exists mysqltest1| +create table t3 (a int)| +insert into t3 (a) values (1), (2)| +create database mysqltest1| +use mysqltest1| +drop database mysqltest1| +select database()| +database() +NULL +select * from (select 1 as a) as t1 natural join (select * from test.t3) as t2| +a +1 +use test| +drop table t3| DROP PROCEDURE IF EXISTS bug16899_p1| DROP FUNCTION IF EXISTS bug16899_f1| CREATE DEFINER=1234567890abcdefGHIKL@localhost PROCEDURE bug16899_p1() @@ -5387,6 +5402,13 @@ ERROR HY000: Can't execute the query because you have a conflicting read lock UNLOCK TABLES| The following should succeed. DROP PROCEDURE bug21414| +set names utf8| +drop database if exists това_е_дълго_име_за_база_данни_нали| +create database това_е_дълго_име_за_база_данни_нали| +INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','')| +call това_е_дълго_име_за_база_данни_нали.това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго()| +ERROR HY000: Failed to load routine това_е_дълго_име_за_база_данни_нали.това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6) +drop database това_е_дълго_име_за_база_данни_нали| CREATE TABLE t3 ( Member_ID varchar(15) NOT NULL, PRIMARY KEY (Member_ID) @@ -5423,8 +5445,6 @@ INSERT INTO t4(Member_ID, Action, Action_Date, Track) VALUES ('666666', 'Enrolled', '2006-05-12', 'CHF' ), ('666666', 'Disenrolled', '2006-06-01', 'CAD' )| DROP FUNCTION IF EXISTS bug21493| -Warnings: -Note 1305 FUNCTION bug21493 does not exist CREATE FUNCTION bug21493(paramMember VARCHAR(15)) RETURNS varchar(45) BEGIN DECLARE tracks VARCHAR(45); @@ -5451,11 +5471,4 @@ CHF DROP FUNCTION bug21493| DROP TABLE t3,t4| End of 5.0 tests -set names utf8| -drop database if exists това_е_дълго_име_за_база_данни_нали| -create database това_е_дълго_име_за_база_данни_нали| -INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','')| -call това_е_дълго_име_за_база_данни_нали.това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго()| -ERROR HY000: Failed to load routine това_е_дълго_име_за_база_данни_нали.. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6) -drop database това_е_дълго_име_за_база_данни_нали| drop table t1,t2; diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result index 637f74a1d50..6c9a389c1f4 100644 --- a/mysql-test/r/temp_table.result +++ b/mysql-test/r/temp_table.result @@ -135,6 +135,23 @@ d c bar 2 foo 1 drop table t1, t2; +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (i INT); +LOCK TABLE t1 WRITE; +CREATE TEMPORARY TABLE t1 (i INT); +The following command should not block +DROP TEMPORARY TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (i INT); +CREATE TEMPORARY TABLE t2 (i INT); +DROP TEMPORARY TABLE t2, t1; +ERROR 42S02: Unknown table 't1' +SELECT * FROM t2; +ERROR 42S02: Table 'test.t2' doesn't exist +SELECT * FROM t1; +i +DROP TABLE t1; +End of 4.1 tests. create temporary table t1 (a int); insert into t1 values (4711); select * from t1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 78bdeb23505..62dc95df7ee 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -6291,6 +6291,41 @@ create procedure bug21416() show create procedure bug21416| call bug21416()| drop procedure bug21416| + +# +# BUG#21414: SP: Procedure undroppable, to some extent +# +--disable_warnings +DROP PROCEDURE IF EXISTS bug21414| +--enable_warnings + +CREATE PROCEDURE bug21414() SELECT 1| + +FLUSH TABLES WITH READ LOCK| + +--error ER_CANT_UPDATE_WITH_READLOCK +DROP PROCEDURE bug21414| + +UNLOCK TABLES| + +--echo The following should succeed. +DROP PROCEDURE bug21414| + + +# +# BUG#21311: Possible stack overrun if SP has non-latin1 name +# +set names utf8| +--disable_warnings +drop database if exists това_е_дълго_име_за_база_данни_нали| +--enable_warnings +create database това_е_дълго_име_за_база_данни_нали| +INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','')| +--error ER_SP_PROC_TABLE_CORRUPT +call това_е_дълго_име_за_база_данни_нали.това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго()| +drop database това_е_дълго_име_за_база_данни_нали| + + # # BUG#21414: SP: Procedure undroppable, to some extent # @@ -6355,9 +6390,9 @@ INSERT INTO t4(Member_ID, Action, Action_Date, Track) VALUES ('666666', 'Enrolled', '2006-05-12', 'CHF' ), ('666666', 'Disenrolled', '2006-06-01', 'CAD' )| -#--disable_warnings +--disable_warnings DROP FUNCTION IF EXISTS bug21493| -#--enable_warnings +--enable_warnings CREATE FUNCTION bug21493(paramMember VARCHAR(15)) RETURNS varchar(45) BEGIN @@ -6380,19 +6415,6 @@ DROP TABLE t3,t4| --echo End of 5.0 tests -# -# BUG#21311: Possible stack overrun if SP has non-latin1 name -# -set names utf8| ---disable_warnings -drop database if exists това_е_дълго_име_за_база_данни_нали| ---enable_warnings -create database това_е_дълго_име_за_база_данни_нали| -INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','')| ---error ER_SP_PROC_TABLE_CORRUPT -call това_е_дълго_име_за_база_данни_нали.това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго()| -drop database това_е_дълго_име_за_база_данни_нали| - # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test index 9121283fb32..123007b10c7 100644 --- a/mysql-test/t/temp_table.test +++ b/mysql-test/t/temp_table.test @@ -116,7 +116,54 @@ insert into t2 values (NULL, 'foo'), (NULL, 'bar'); select d, c from t1 left join t2 on b = c where a = 3 order by d; drop table t1, t2; -# End of 4.1 tests + +# +# BUG#21096: locking issue ; temporary table conflicts. +# +# The problem was that on DROP TEMPORARY table name lock was acquired, +# which should not be done. +# +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (i INT); + +LOCK TABLE t1 WRITE; + +connect (conn1, localhost, root,,); + +CREATE TEMPORARY TABLE t1 (i INT); + +--echo The following command should not block +DROP TEMPORARY TABLE t1; + +disconnect conn1; +connection default; + +DROP TABLE t1; + +# +# Check that it's not possible to drop a base table with +# DROP TEMPORARY statement. +# +CREATE TABLE t1 (i INT); +CREATE TEMPORARY TABLE t2 (i INT); + +--error 1051 +DROP TEMPORARY TABLE t2, t1; + +# Table t2 should have been dropped. +--error 1146 +SELECT * FROM t2; +# But table t1 should still be there. +SELECT * FROM t1; + +DROP TABLE t1; + + +--echo End of 4.1 tests. + # # Test truncate with temporary tables diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 63b81c10067..e195b2b71ac 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1137,17 +1137,28 @@ JOIN::optimize() tmp_table_param.hidden_field_count= (all_fields.elements - fields_list.elements); + ORDER *tmp_group= ((!simple_group && !procedure && + !(test_flags & TEST_NO_KEY_GROUP)) ? group_list : + (ORDER*) 0); + /* + Pushing LIMIT to the temporary table creation is not applicable + when there is ORDER BY or GROUP BY or there is no GROUP BY, but + there are aggregate functions, because in all these cases we need + all result rows. + */ + ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order || + test(select_options & OPTION_BUFFER_RESULT)) && + !tmp_group && + !thd->lex->current_select->with_sum_func) ? + select_limit : HA_POS_ERROR; + if (!(exec_tmp_table1= create_tmp_table(thd, &tmp_table_param, all_fields, - ((!simple_group && !procedure && - !(test_flags & TEST_NO_KEY_GROUP)) ? - group_list : (ORDER*) 0), + tmp_group, group_list ? 0 : select_distinct, group_list && simple_group, select_options, - (order == 0 || skip_sort_order || - test(select_options & OPTION_BUFFER_RESULT)) ? - select_limit : HA_POS_ERROR, + tmp_rows_limit, (char *) ""))) DBUG_RETURN(1); @@ -9197,6 +9208,13 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, thd->variables.max_heap_table_size) : thd->variables.tmp_table_size)/ share->reclength); set_if_bigger(share->max_rows,1); // For dummy start options + /* + Push the LIMIT clause to the temporary table creation, so that we + materialize only up to 'rows_limit' records instead of all result records. + */ + set_if_smaller(share->max_rows, rows_limit); + param->end_write_records= rows_limit; + keyinfo= param->keyinfo; if (group) @@ -9329,19 +9347,6 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } } - /* - Push the LIMIT clause to the temporary table creation, so that we - materialize only up to 'rows_limit' records instead of all result records. - This optimization is not applicable when there is GROUP BY or there is - no GROUP BY, but there are aggregate functions, because both must be - computed for all result rows. - */ - if (!group && !thd->lex->current_select->with_sum_func) - { - set_if_smaller(table->s->max_rows, rows_limit); - param->end_write_records= rows_limit; - } - if (thd->is_fatal_error) // If end of memory goto err; /* purecov: inspected */ share->db_record_offset= 1; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bb8223f1d81..6f8deab220e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1633,7 +1633,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, } } - if (lock_table_names(thd, tables)) + if (!drop_temporary && lock_table_names(thd, tables)) DBUG_RETURN(1); /* Don't give warnings for not found errors, as we already generate notes */ @@ -1818,7 +1818,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, } } - unlock_table_names(thd, tables, (TABLE_LIST*) 0); + if (!drop_temporary) + unlock_table_names(thd, tables, (TABLE_LIST*) 0); thd->no_warnings_for_error= 0; DBUG_RETURN(error); }