diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 2c738c47deb..29200a43975 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -135,6 +135,26 @@ cbv1 4711 delete from t1; drop procedure cbv1; drop procedure cbv2; +insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3); +create procedure sub1(id char(16), x int) +insert into test.t1 values (id, x); +create function sub3(i int) returns int +return i+1; +call sub1("sub1a", (select 7)); +call sub1("sub1b", (select max(i) from t2)); +call sub1("sub1c", (select i,d from t2 limit 1)); +call sub1("sub1d", (select 1 from (select 1) a)); +select * from t1; +id data +sub1a 7 +sub1b 3 +sub1c 1 +sub1d 1 +select sub3((select max(i) from t2)); +sub3((select max(i) from t2)) +4 +drop procedure sub1; +drop function sub3; create procedure a0(x int) while x do set x = x-1; @@ -143,6 +163,10 @@ end while; call a0(3); select * from t1; id data +sub1a 7 +sub1b 3 +sub1c 1 +sub1d 1 a0 2 a0 1 a0 0 @@ -391,6 +415,9 @@ s i d xxxyyy 12 2.71828182845905 select * from t2; s i d +a 1 1.1 +b 2 1.2 +c 3 1.3 xxxyyy 12 2.71828182845905 ab 24 1324.36598821719 delete from t2; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index b34503c34c2..3c34e615dab 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -887,23 +887,6 @@ do (SELECT a from t1); Table 'test.t1' doesn't exist set @a:=(SELECT a from t1); Table 'test.t1' doesn't exist -create table t1 (a int); -create table t2 (a int); -insert into t2 values (1), (2), (3); -create procedure foo1(x int) -insert into test.t1 values (x); -create function foo2(i int) returns int -return i+1; -call foo1((select max(a) from t2)); -select * from t1; -a -3 -select foo2((select max(a) from t2)); -foo2((select max(a) from t2)) -4 -drop table t1, t2; -drop procedure foo1; -drop function foo2; CREATE TABLE t1 (a int, KEY(a)); HANDLER t1 OPEN; HANDLER t1 READ a=((SELECT 1)); diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 294b61514fa..c501501b82f 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -175,6 +175,36 @@ drop procedure cbv1| drop procedure cbv2| +# Subselect arguments + +insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3)| + +create procedure sub1(id char(16), x int) + insert into test.t1 values (id, x)| + +# QQ This doesn't work yet +#create procedure sub2(id char(16)) +#begin +# declare x int; +# set x = (select sum(t.x) from test.t2 t); +# insert into test.t1 values (id, x); +#end| + +create function sub3(i int) returns int + return i+1| + +call sub1("sub1a", (select 7))| +call sub1("sub1b", (select max(i) from t2))| +call sub1("sub1c", (select i,d from t2 limit 1))| +call sub1("sub1d", (select 1 from (select 1) a))| +#call sub2("sub2"); +select * from t1| +select sub3((select max(i) from t2))| +drop procedure sub1| +#drop procedure sub2| +drop function sub3| + + # Basic tests of the flow control constructs # Just test on 'x'... diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 3e868fd0add..ff40695de47 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -502,22 +502,6 @@ do (SELECT a from t1); -- error 1146 set @a:=(SELECT a from t1); -# -# CALL -# -create table t1 (a int); -create table t2 (a int); -insert into t2 values (1), (2), (3); -create procedure foo1(x int) - insert into test.t1 values (x); -create function foo2(i int) returns int - return i+1; -call foo1((select max(a) from t2)); -select * from t1; -select foo2((select max(a) from t2)); -drop table t1, t2; -drop procedure foo1; -drop function foo2; CREATE TABLE t1 (a int, KEY(a)); HANDLER t1 OPEN; diff --git a/sql/sp.cc b/sql/sp.cc index 9e0d848b19d..0d6a7b99e32 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -105,7 +105,7 @@ db_find_routine(THD *thd, int type, char *name, uint namelen, sp_head **sphp) } if (opened) { - close_thread_tables(thd); + close_thread_tables(thd, 0, 1); table= NULL; } @@ -286,7 +286,7 @@ sp_function_exists(THD *thd, LEX_STRING *name) ret= TRUE; } if (opened) - close_thread_tables(thd); + close_thread_tables(thd, 0, 1); return ret; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ce908afb19f..3bd958cfba9 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -80,7 +80,7 @@ eval_func_item(THD *thd, Item *it, enum enum_field_types type) String tmp(buffer, sizeof(buffer), it->charset()); String *s= it->val_str(&tmp); - DBUG_PRINT("info", ("default result: %*s", s->length(), s->c_ptr_quick())) + DBUG_PRINT("info",("default result: %*s",s->length(),s->c_ptr_quick())); it= new Item_string(sql_strmake(s->c_ptr_quick(), s->length()), s->length(), it->charset()); break; @@ -393,7 +393,7 @@ sp_head::restore_lex(THD *thd) // Collect some data from the sub statement lex. sp_merge_funs(&m_lex, &thd->lex); #if 0 - // We're not using this at the moment. + // QQ We're not using this at the moment. if (thd->lex.sql_command == SQLCOM_CALL) { // It would be slightly faster to keep the list sorted, but we need diff --git a/sql/sp_head.h b/sql/sp_head.h index b79dfdab8e9..b0685ba7ca3 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -49,7 +49,7 @@ public: my_bool m_multi_query; // TRUE if a procedure with SELECT(s) uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value #if 0 - // We're not using this at the moment. + // QQ We're not using this at the moment. List m_calls; // Called procedures. List m_tables; // Used tables. #endif diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index ca761140955..9db7f172776 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -199,7 +199,13 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, else unit->exclude_level(); org_table_list->db= (char *)""; -#ifndef DBUG_OFF +#if 0 + /* QQ This was #ifndef DBUG_OFF, but that caused crashes with + * certain subselect args to SPs. Since ->derived is tested + * for non-null value in some places in the code, this seems + * to be the wrong way to do it. Simply letting derived be 0 + * appears to work fine. /pem + */ /* Try to catch errors if this is accessed */ org_table_list->derived=(SELECT_LEX_UNIT *) 1; #endif diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4b077f4454b..28ec89f40da 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3060,9 +3060,13 @@ mysql_execute_command(THD *thd) uint smrx; LINT_INIT(smrx); + // In case the arguments are subselects... if (tables && ((res= check_table_access(thd, SELECT_ACL, tables)) || - (res= open_and_lock_tables(thd,tables)))) + (res= open_and_lock_tables(thd, tables)))) + { + sp->destroy(); // QQ Free memory. Remove this when caching!!! break; + } fix_tables_pointers(lex->all_selects_list); #ifndef EMBEDDED_LIBRARY diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index dba829d2183..d5ca5a172b7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1399,7 +1399,8 @@ sp_labeled_control: LEX *lex= Lex; sp_label_t *lab= lex->spcont->find_label($5.str); - if (! lab || strcasecmp($5.str, lab->name) != 0) + if (!lab || + my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) { net_printf(YYTHD, ER_SP_LABEL_MISMATCH, $5.str); YYABORT;