summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bell@laptop.sanja.is.com.ua>2003-10-06 12:08:28 +0300
committerunknown <bell@laptop.sanja.is.com.ua>2003-10-06 12:08:28 +0300
commit84285351be6b99f771af663085feda2670d36638 (patch)
treefb79dae1b7c2d199bada6e1802519c5ab1664fc1
parentd2574b928e728cbe4c0551b91c528ea13b6dc579 (diff)
parent4379cbcf3056a33f41ddf489828203a6c03e793f (diff)
downloadmariadb-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
-rw-r--r--include/mysqld_error.h4
-rw-r--r--mysql-test/r/sp-error.result17
-rw-r--r--mysql-test/r/sp.result17
-rw-r--r--mysql-test/t/sp-error.test23
-rw-r--r--mysql-test/t/sp.test17
-rw-r--r--sql/share/czech/errmsg.txt2
-rw-r--r--sql/share/danish/errmsg.txt2
-rw-r--r--sql/share/dutch/errmsg.txt2
-rw-r--r--sql/share/english/errmsg.txt2
-rw-r--r--sql/share/estonian/errmsg.txt2
-rw-r--r--sql/share/french/errmsg.txt2
-rw-r--r--sql/share/german/errmsg.txt2
-rw-r--r--sql/share/greek/errmsg.txt2
-rw-r--r--sql/share/hungarian/errmsg.txt2
-rw-r--r--sql/share/italian/errmsg.txt2
-rw-r--r--sql/share/japanese/errmsg.txt2
-rw-r--r--sql/share/korean/errmsg.txt2
-rw-r--r--sql/share/norwegian-ny/errmsg.txt2
-rw-r--r--sql/share/norwegian/errmsg.txt2
-rw-r--r--sql/share/polish/errmsg.txt2
-rw-r--r--sql/share/portuguese/errmsg.txt2
-rw-r--r--sql/share/romanian/errmsg.txt2
-rw-r--r--sql/share/russian/errmsg.txt2
-rw-r--r--sql/share/serbian/errmsg.txt2
-rw-r--r--sql/share/slovak/errmsg.txt2
-rw-r--r--sql/share/spanish/errmsg.txt2
-rw-r--r--sql/share/swedish/errmsg.txt2
-rw-r--r--sql/share/ukrainian/errmsg.txt2
-rw-r--r--sql/sp_head.cc41
-rw-r--r--sql/sp_head.h1
-rw-r--r--sql/sql_parse.cc7
-rw-r--r--sql/sql_yacc.yy9
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