From 3aaa8ab94e868a81b3e8935a3aca6aa93a818431 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 15:17:55 +0100 Subject: [PATCH] Fixed BUG#336: Subselects with tables does not work as values for local SP variables and BUG#1654: Stored Procedure Crash if contains subquery and set function Disallowed subselects in RETURN (for FUNCTIONs) and SET of local variables. The latter should work, but turned out to be difficult to fix, so we just disallow it for the time being. include/mysqld_error.h: New error message for unsupported subselect as SP set values (for the time being). include/sql_state.h: New error message for unsupported subselect as SP set values (for the time being). mysql-test/r/sp-error.result: Test cases for BUG#336 and BUG#1654. (Unsupported use of subselect) mysql-test/t/sp-error.test: Test cases for BUG#336 and BUG#1654. (Unsupported use of subselect) sql/item.cc: Made Item_splocal::type() work at compile time, for error checking. sql/item.h: Made Item_splocal::type() work at compile time, for error checking. sql/share/czech/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/danish/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/dutch/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/english/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/estonian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/french/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/german/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/greek/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/hungarian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/italian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/japanese/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/korean/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/norwegian-ny/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/norwegian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/polish/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/portuguese/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/romanian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/russian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/serbian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/slovak/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/spanish/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/swedish/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/ukrainian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/sp_head.cc: Fixed (bogus) compile error on HP-UX alpha. sql/sql_yacc.yy: Disallowed subselects in RETURN (for FUNCTIONs) and SET of local variables. The latter should work, but turned out to be difficult to fix, so we just disallow it for the time being. --- include/mysqld_error.h | 3 ++- include/sql_state.h | 1 + mysql-test/r/sp-error.result | 10 ++++++++++ mysql-test/t/sp-error.test | 17 +++++++++++++++++ sql/item.cc | 11 +++++++++++ sql/item.h | 5 +---- sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + sql/sp_head.cc | 5 +++-- sql/sql_yacc.yy | 16 +++++++++++++--- 31 files changed, 81 insertions(+), 10 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 6b2e5115a4e..e203c13178e 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -333,4 +333,5 @@ #define ER_SP_DUP_COND 1314 #define ER_SP_DUP_CURS 1315 #define ER_SP_CANT_ALTER 1316 -#define ER_ERROR_MESSAGES 317 +#define ER_SP_SUBSELECT_NYI 1317 +#define ER_ERROR_MESSAGES 318 diff --git a/include/sql_state.h b/include/sql_state.h index 363632bc167..d206c659b60 100644 --- a/include/sql_state.h +++ b/include/sql_state.h @@ -194,3 +194,4 @@ ER_SP_DUP_VAR, "42000", "", ER_SP_DUP_COND, "42000", "", ER_SP_DUP_CURS, "42000", "", /*ER_SP_CANT_ALTER*/ +ER_SP_SUBSELECT_NYI, "0A000", "", diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index a1ac2a85b6e..37be3454812 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -270,4 +270,14 @@ ERROR 42S22: Unknown column 'valname' in 'order clause' drop procedure bug1965; select 1 into a; ERROR 42000: Undeclared variable: a +create procedure bug336(id char(16)) +begin +declare x int; +set x = (select sum(t.data) from test.t2 t); +end; +ERROR 0A000: Subselect value not supported +create function bug1654() +returns int +return (select sum(t.data) from test.t2 t); +ERROR 0A000: Statements like SELECT, INSERT, UPDATE (and others) are not allowed in a FUNCTION drop table t1; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 50a8b8c8768..32fbac2e92f 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -361,6 +361,23 @@ drop procedure bug1965| --error 1309 select 1 into a| +# +# BUG#336 +# +--error 1317 +create procedure bug336(id char(16)) +begin + declare x int; + set x = (select sum(t.data) from test.t2 t); +end| + +# +# BUG#1654 +# +--error 1296 +create function bug1654() + returns int +return (select sum(t.data) from test.t2 t)| drop table t1| diff --git a/sql/item.cc b/sql/item.cc index 2f089544761..71483bf88d4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -240,6 +240,17 @@ Item_splocal::this_const_item() const return thd->spcont->get_item(m_offset); } +Item::Type +Item_splocal::type() const +{ + THD *thd= current_thd; + + if (thd->spcont) + return thd->spcont->get_item(m_offset)->type(); + return NULL_ITEM; // Anything but SUBSELECT_ITEM +} + + bool DTCollation::aggregate(DTCollation &dt) { if (!my_charset_same(collation, dt.collation)) diff --git a/sql/item.h b/sql/item.h index a7742f41b56..d8aea6552c3 100644 --- a/sql/item.h +++ b/sql/item.h @@ -260,10 +260,7 @@ public: // Abstract methods inherited from Item. Just defer the call to // the item in the frame - inline enum Type type() const - { - return this_const_item()->type(); - } + enum Type type() const; inline double val() { diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 5cf1dd2a47c..76c936019a0 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -329,3 +329,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 69e14c6acf3..6bacfe53b2c 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -323,3 +323,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 386ff34ef59..f45fc31b293 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -331,3 +331,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 2e159d40e40..f68d65467bb 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -320,3 +320,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index e03f60ac040..12e33f48b31 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -325,3 +325,4 @@ character-set=latin7 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index b3591e2f4ab..92c831604d3 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -320,3 +320,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 6a404b2083f..fcd8028863a 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -332,3 +332,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 47cb5125dbb..e5ac5e872ce 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -320,3 +320,4 @@ character-set=greek "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index cbe34d19fe1..ace96dd1420 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 6f7aaaec669..9b4b6f8c601 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -320,3 +320,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index ee9a546cb11..53d39211378 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -322,3 +322,4 @@ character-set=ujis "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 6aa94a4482a..1abf59b2456 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -320,3 +320,4 @@ character-set=euckr "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 65faac4365c..2f14cdcc042 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 26d0bae406f..d086345f97b 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 55e3d9dc1dc..c0333f2b643 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -324,3 +324,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 519434c24b5..1c307d60b25 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -321,3 +321,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 5c6ecd8ddd7..4bb0dd981ae 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -324,3 +324,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 6f0dd2d9ac7..7aab4d23f44 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -322,3 +322,4 @@ character-set=koi8r "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index e9be8102e0e..f32593c6441 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -315,3 +315,4 @@ character-set=cp1250 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index af3eae4f97b..6dccde95e25 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -328,3 +328,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index b799ce54bec..dcadd07e73e 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 40fc31dfdb3..8189d43fdbb 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -320,3 +320,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index e0d42d6264b..c95fd62e104 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -325,3 +325,4 @@ character-set=koi8u "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 70810265926..26cf30234d2 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -714,6 +714,7 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) { LEX *olex; // The other lex Item *freelist; + SELECT_LEX *sl; int res; olex= thd->lex; // Save the other lex @@ -726,7 +727,7 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) // Copy WHERE clause pointers to avoid damaging by optimisation // Also clear ref_pointer_arrays. - for (SELECT_LEX *sl= lex->all_selects_list ; + for (sl= lex->all_selects_list ; sl ; sl= sl->next_select_in_list()) { @@ -772,7 +773,7 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) close_thread_tables(thd); /* Free tables */ } - for (SELECT_LEX *sl= lex->all_selects_list ; + for (sl= lex->all_selects_list ; sl ; sl= sl->next_select_in_list()) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7e7a8976924..bf346bc24d9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1548,10 +1548,15 @@ sp_proc_stmt: } else { - sp_instr_freturn *i= - new sp_instr_freturn(lex->sphead->instructions(), - $2, lex->sphead->m_returns); + sp_instr_freturn *i; + if ($2->type() == Item::SUBSELECT_ITEM) + { /* QQ For now, just disallow subselects as values */ + send_error(lex->thd, ER_SP_BADSTATEMENT); + YYABORT; + } + i= new sp_instr_freturn(lex->sphead->instructions(), + $2, lex->sphead->m_returns); lex->sphead->add_instr(i); lex->sphead->m_has_return= TRUE; } @@ -5933,6 +5938,11 @@ option_value: } else { /* An SP local variable */ + if ($3 && $3->type() == Item::SUBSELECT_ITEM) + { /* QQ For now, just disallow subselects as values */ + send_error(lex->thd, ER_SP_SUBSELECT_NYI); + YYABORT; + } sp_pvar_t *spv= lex->spcont->find_pvar(&$1.base_name); sp_instr_set *i= new sp_instr_set(lex->sphead->instructions(), spv->offset, $3, spv->type);