diff options
author | unknown <bell@laptop.sanja.is.com.ua> | 2003-10-06 12:08:28 +0300 |
---|---|---|
committer | unknown <bell@laptop.sanja.is.com.ua> | 2003-10-06 12:08:28 +0300 |
commit | 84285351be6b99f771af663085feda2670d36638 (patch) | |
tree | fb79dae1b7c2d199bada6e1802519c5ab1664fc1 | |
parent | d2574b928e728cbe4c0551b91c528ea13b6dc579 (diff) | |
parent | 4379cbcf3056a33f41ddf489828203a6c03e793f (diff) | |
download | mariadb-git-84285351be6b99f771af663085feda2670d36638.tar.gz |
Merge laptop.sanja.is.com.ua:/home/bell/mysql/bk/mysql-5.0
into laptop.sanja.is.com.ua:/home/bell/mysql/bk/work-udf-5.0
sql/sql_parse.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
32 files changed, 176 insertions, 6 deletions
diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 7f317e93604..18283d576ad 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -312,4 +312,6 @@ #define ER_QUERY_INTERRUPTED 1293 #define ER_SP_WRONG_NO_OF_ARGS 1294 #define ER_SP_COND_MISMATCH 1295 -#define ER_ERROR_MESSAGES 296 +#define ER_SP_NORETURN 1296 +#define ER_SP_NORETURNEND 1297 +#define ER_ERROR_MESSAGES 298 diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 109d84b2b8a..d90aef7f609 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -121,3 +121,20 @@ set res = 1; end if; end; ERROR HY000: Undefined CONDITION: bar +create function f(val int) returns int +begin +declare x int; +set x = val+3; +end; +ERROR HY000: No RETURN found in FUNCTION f +create function f(val int) returns int +begin +declare x int; +set x = val+3; +if x < 4 then +return x; +end if; +end; +select f(10); +ERROR HY000: FUNCTION f ended without RETURN +drop function f; diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 42f720c7791..c8652b25b2e 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -500,6 +500,23 @@ id data hndlr3 13 delete from t1; drop procedure hndlr3; +create procedure bug822(a_id char(16), a_data int) +begin +declare n int; +select count(*) into n from t1 where id = a_id and data = a_data; +if n = 0 then +insert into t1 (id, data) values (a_id, a_data); +end if; +end; +call bug822('foo', 42); +call bug822('foo', 42); +call bug822('bar', 666); +select * from t1; +id data +foo 42 +bar 666 +delete from t1; +drop procedure bug822; drop table if exists fac; create table fac (n int unsigned not null primary key, f bigint unsigned); create procedure ifac(n int unsigned) diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index ab3ee6a9ac6..ba2805bfb0c 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -171,4 +171,27 @@ begin end if; end| +--error 1296 +create function f(val int) returns int +begin + declare x int; + + set x = val+3; +end| + +create function f(val int) returns int +begin + declare x int; + + set x = val+3; + if x < 4 then + return x; + end if; +end| + +--error 1297 +select f(10)| + +drop function f| + delimiter ;| diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 3450b47b4e5..43deb12b379 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -589,6 +589,23 @@ delete from t1| drop procedure hndlr3| +create procedure bug822(a_id char(16), a_data int) +begin + declare n int; + select count(*) into n from t1 where id = a_id and data = a_data; + if n = 0 then + insert into t1 (id, data) values (a_id, a_data); + end if; +end| + +call bug822('foo', 42)| +call bug822('foo', 42)| +call bug822('bar', 666)| +select * from t1| +delete from t1| +drop procedure bug822| + + # # Some "real" examples # diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 384eb42f6f1..d572b3e4b29 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -308,3 +308,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index e621faea5fe..c83c6ce000e 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -302,3 +302,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index b5a30826996..7001dc859b9 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -310,3 +310,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 1d791bd8609..3936957fad8 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -299,3 +299,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 03c66e69a04..7d85d53b9ce 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -304,3 +304,5 @@ character-set=latin7 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 79cef951367..a3dcdea06c0 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -299,3 +299,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 2e821cbcaab..59735b8bb5d 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -308,3 +308,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 083c158b775..bcfd619a0a1 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -299,3 +299,5 @@ character-set=greek "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index f48f9002186..c4a4cdb1fb6 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -301,3 +301,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 6aa63898d7b..3e1034c8c4a 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -299,3 +299,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 674cf949c37..eb2e456fa66 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -301,3 +301,5 @@ character-set=ujis "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index e39178a3a8a..82f55bb7b02 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -299,3 +299,5 @@ character-set=euckr "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index ccb8fa61fed..74b5fbfbb65 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -301,3 +301,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 7ef83310089..ac08124cf26 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -301,3 +301,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index faa4a4fae10..86dd51da336 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -303,3 +303,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 8ba445c9c31..6e55a8c071e 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -300,3 +300,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 094b5fd76cb..50521fbef94 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -303,3 +303,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index a51ecd4934b..f4ef5415136 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -301,3 +301,5 @@ character-set=koi8r "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index f5a5b88410e..83adc33c73b 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -294,3 +294,5 @@ character-set=cp1250 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 02a2f281374..fc4cb769bc8 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -307,3 +307,5 @@ character-set=latin2 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 007f2b457f9..129df358d2e 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -301,3 +301,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 7cde684afe3..e17e20aa5f5 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -299,3 +299,5 @@ character-set=latin1 "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 4ff6754079d..cb29db0330e 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -304,3 +304,5 @@ character-set=koi8u "Query execution was interrupted" "Wrong number of arguments for %s %s, expected %u, got %u" "Undefined CONDITION: %s" +"No RETURN found in FUNCTION %s" +"FUNCTION %s ended without RETURN" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index f34cb39ab7d..82afb9305f0 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -120,7 +120,8 @@ sp_head::operator delete(void *ptr, size_t size) } sp_head::sp_head() - : Sql_alloc(), m_simple_case(FALSE), m_multi_results(FALSE), m_free_list(NULL) + : Sql_alloc(), m_has_return(FALSE), m_simple_case(FALSE), + m_multi_results(FALSE), m_free_list(NULL) { DBUG_ENTER("sp_head::sp_head"); @@ -321,7 +322,18 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) ret= execute(thd); if (ret == 0) - *resp= nctx->get_result(); + { + Item *it= nctx->get_result(); + + if (it) + *resp= it; + else + { + my_printf_error(ER_SP_NORETURNEND, ER(ER_SP_NORETURNEND), MYF(0), + m_name.str); + ret= -1; + } + } thd->spcont= octx; DBUG_RETURN(ret); @@ -481,6 +493,13 @@ sp_head::restore_lex(THD *thd) // Update some state in the old one first oldlex->ptr= sublex->ptr; oldlex->next_state= sublex->next_state; + // Save WHERE clause pointers to avoid damaging by optimisation + for (SELECT_LEX *sl= sublex->all_selects_list ; + sl ; + sl= sl->next_select_in_list()) + { + sl->prep_where= sl->where; + } // Collect some data from the sub statement lex. sp_merge_funs(oldlex, sublex); @@ -578,14 +597,31 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) DBUG_ENTER("sp_instr_stmt::execute"); DBUG_PRINT("info", ("command: %d", m_lex->sql_command)); LEX *olex; // The other lex + Item *freelist; int res; olex= thd->lex; // Save the other lex thd->lex= m_lex; // Use my own lex thd->lex->thd = thd; // QQ Not reentrant! thd->lex->unit.thd= thd; // QQ Not reentrant + freelist= thd->free_list; + thd->free_list= NULL; + thd->query_id= query_id++; + + // Copy WHERE clause pointers to avoid damaging by optimisation + // Also clear ref_pointer_arrays. + for (SELECT_LEX *sl= m_lex->all_selects_list ; + sl ; + sl= sl->next_select_in_list()) + { + sl->ref_pointer_array= 0; + if (sl->prep_where) + sl->where= sl->prep_where->copy_andor_structure(thd); + DBUG_ASSERT(sl->join == 0); + } res= mysql_execute_command(thd); + if (thd->lock || thd->open_tables || thd->derived_tables) { thd->proc_info="closing tables"; @@ -593,6 +629,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) } thd->lex= olex; // Restore the other lex + thd->free_list= freelist; *nextp = m_ip+1; DBUG_RETURN(res); diff --git a/sql/sp_head.h b/sql/sp_head.h index e7dbd3f68a6..a68a1bf83ef 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -47,6 +47,7 @@ public: int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE enum enum_field_types m_returns; // For FUNCTIONs only + my_bool m_has_return; // For FUNCTIONs only my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise my_bool m_multi_results; // TRUE if a procedure with SELECT(s) uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 93f5bf99ebe..5c61247136f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3226,6 +3226,13 @@ mysql_execute_command(THD *thd) } } #endif + if (lex->sphead->m_type == TYPE_ENUM_FUNCTION && + !lex->sphead->m_has_return) + { + net_printf(thd, ER_SP_NORETURN, name); + goto error; + } + res= lex->sphead->create(thd); switch (res) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ebf3ebf6b35..673ee85ddb5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1425,6 +1425,7 @@ sp_proc_stmt: $2, lex->sphead->m_returns); lex->sphead->add_instr(i); + lex->sphead->m_has_return= TRUE; } } | IF sp_if END IF {} @@ -1645,13 +1646,15 @@ sp_unlabeled_control: LEX *lex= Lex; sp_head *sp= lex->sphead; sp_pcontext *ctx= lex->spcont; - sp_instr_hpop *i; sp->backpatch(ctx->pop_label()); ctx->pop_pvar($3.vars); ctx->pop_cond($3.conds); - i= new sp_instr_hpop(sp->instructions(), $3.hndlrs); - sp->add_instr(i); + if ($3.hndlrs) + { + sp_instr_hpop *i= new sp_instr_hpop(sp->instructions(),$3.hndlrs); + sp->add_instr(i); + } } | LOOP_SYM sp_proc_stmts END LOOP_SYM |