Commit 311964f5 authored by bell@laptop.sanja.is.com.ua's avatar bell@laptop.sanja.is.com.ua

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
parents b0b87a11 e8634f80
...@@ -312,4 +312,6 @@ ...@@ -312,4 +312,6 @@
#define ER_QUERY_INTERRUPTED 1293 #define ER_QUERY_INTERRUPTED 1293
#define ER_SP_WRONG_NO_OF_ARGS 1294 #define ER_SP_WRONG_NO_OF_ARGS 1294
#define ER_SP_COND_MISMATCH 1295 #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
...@@ -121,3 +121,20 @@ set res = 1; ...@@ -121,3 +121,20 @@ set res = 1;
end if; end if;
end; end;
ERROR HY000: Undefined CONDITION: bar 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;
...@@ -500,6 +500,23 @@ id data ...@@ -500,6 +500,23 @@ id data
hndlr3 13 hndlr3 13
delete from t1; delete from t1;
drop procedure hndlr3; 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; drop table if exists fac;
create table fac (n int unsigned not null primary key, f bigint unsigned); create table fac (n int unsigned not null primary key, f bigint unsigned);
create procedure ifac(n int unsigned) create procedure ifac(n int unsigned)
......
...@@ -171,4 +171,27 @@ begin ...@@ -171,4 +171,27 @@ begin
end if; end if;
end| 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 ;| delimiter ;|
...@@ -589,6 +589,23 @@ delete from t1| ...@@ -589,6 +589,23 @@ delete from t1|
drop procedure hndlr3| 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 # Some "real" examples
# #
......
...@@ -308,3 +308,5 @@ character-set=latin2 ...@@ -308,3 +308,5 @@ character-set=latin2
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -302,3 +302,5 @@ character-set=latin1 ...@@ -302,3 +302,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -310,3 +310,5 @@ character-set=latin1 ...@@ -310,3 +310,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -299,3 +299,5 @@ character-set=latin1 ...@@ -299,3 +299,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -304,3 +304,5 @@ character-set=latin7 ...@@ -304,3 +304,5 @@ character-set=latin7
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -299,3 +299,5 @@ character-set=latin1 ...@@ -299,3 +299,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -308,3 +308,5 @@ character-set=latin1 ...@@ -308,3 +308,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -299,3 +299,5 @@ character-set=greek ...@@ -299,3 +299,5 @@ character-set=greek
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -301,3 +301,5 @@ character-set=latin2 ...@@ -301,3 +301,5 @@ character-set=latin2
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -299,3 +299,5 @@ character-set=latin1 ...@@ -299,3 +299,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -301,3 +301,5 @@ character-set=ujis ...@@ -301,3 +301,5 @@ character-set=ujis
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -299,3 +299,5 @@ character-set=euckr ...@@ -299,3 +299,5 @@ character-set=euckr
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -301,3 +301,5 @@ character-set=latin1 ...@@ -301,3 +301,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -301,3 +301,5 @@ character-set=latin1 ...@@ -301,3 +301,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -303,3 +303,5 @@ character-set=latin2 ...@@ -303,3 +303,5 @@ character-set=latin2
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -300,3 +300,5 @@ character-set=latin1 ...@@ -300,3 +300,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -303,3 +303,5 @@ character-set=latin2 ...@@ -303,3 +303,5 @@ character-set=latin2
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -301,3 +301,5 @@ character-set=koi8r ...@@ -301,3 +301,5 @@ character-set=koi8r
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -294,3 +294,5 @@ character-set=cp1250 ...@@ -294,3 +294,5 @@ character-set=cp1250
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -307,3 +307,5 @@ character-set=latin2 ...@@ -307,3 +307,5 @@ character-set=latin2
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -301,3 +301,5 @@ character-set=latin1 ...@@ -301,3 +301,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -299,3 +299,5 @@ character-set=latin1 ...@@ -299,3 +299,5 @@ character-set=latin1
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -304,3 +304,5 @@ character-set=koi8u ...@@ -304,3 +304,5 @@ character-set=koi8u
"Query execution was interrupted" "Query execution was interrupted"
"Wrong number of arguments for %s %s, expected %u, got %u" "Wrong number of arguments for %s %s, expected %u, got %u"
"Undefined CONDITION: %s" "Undefined CONDITION: %s"
"No RETURN found in FUNCTION %s"
"FUNCTION %s ended without RETURN"
...@@ -120,7 +120,8 @@ sp_head::operator delete(void *ptr, size_t size) ...@@ -120,7 +120,8 @@ sp_head::operator delete(void *ptr, size_t size)
} }
sp_head::sp_head() 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"); DBUG_ENTER("sp_head::sp_head");
...@@ -321,7 +322,18 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp) ...@@ -321,7 +322,18 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
ret= execute(thd); ret= execute(thd);
if (ret == 0) 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; thd->spcont= octx;
DBUG_RETURN(ret); DBUG_RETURN(ret);
...@@ -481,6 +493,13 @@ sp_head::restore_lex(THD *thd) ...@@ -481,6 +493,13 @@ sp_head::restore_lex(THD *thd)
// Update some state in the old one first // Update some state in the old one first
oldlex->ptr= sublex->ptr; oldlex->ptr= sublex->ptr;
oldlex->next_state= sublex->next_state; 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. // Collect some data from the sub statement lex.
sp_merge_funs(oldlex, sublex); sp_merge_funs(oldlex, sublex);
...@@ -578,14 +597,31 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) ...@@ -578,14 +597,31 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
DBUG_ENTER("sp_instr_stmt::execute"); DBUG_ENTER("sp_instr_stmt::execute");
DBUG_PRINT("info", ("command: %d", m_lex->sql_command)); DBUG_PRINT("info", ("command: %d", m_lex->sql_command));
LEX *olex; // The other lex LEX *olex; // The other lex
Item *freelist;
int res; int res;
olex= thd->lex; // Save the other lex olex= thd->lex; // Save the other lex
thd->lex= m_lex; // Use my own lex thd->lex= m_lex; // Use my own lex
thd->lex->thd = thd; // QQ Not reentrant! thd->lex->thd = thd; // QQ Not reentrant!
thd->lex->unit.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); res= mysql_execute_command(thd);
if (thd->lock || thd->open_tables || thd->derived_tables) if (thd->lock || thd->open_tables || thd->derived_tables)
{ {
thd->proc_info="closing tables"; thd->proc_info="closing tables";
...@@ -593,6 +629,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) ...@@ -593,6 +629,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
} }
thd->lex= olex; // Restore the other lex thd->lex= olex; // Restore the other lex
thd->free_list= freelist;
*nextp = m_ip+1; *nextp = m_ip+1;
DBUG_RETURN(res); DBUG_RETURN(res);
......
...@@ -47,6 +47,7 @@ public: ...@@ -47,6 +47,7 @@ public:
int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE
enum enum_field_types m_returns; // For FUNCTIONs only 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_simple_case; // TRUE if parsing simple case, FALSE otherwise
my_bool m_multi_results; // TRUE if a procedure with SELECT(s) my_bool m_multi_results; // TRUE if a procedure with SELECT(s)
uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value uint m_old_cmq; // Old CLIENT_MULTI_QUERIES value
......
...@@ -3226,6 +3226,13 @@ mysql_execute_command(THD *thd) ...@@ -3226,6 +3226,13 @@ mysql_execute_command(THD *thd)
} }
} }
#endif #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); res= lex->sphead->create(thd);
switch (res) switch (res)
......
...@@ -1425,6 +1425,7 @@ sp_proc_stmt: ...@@ -1425,6 +1425,7 @@ sp_proc_stmt:
$2, lex->sphead->m_returns); $2, lex->sphead->m_returns);
lex->sphead->add_instr(i); lex->sphead->add_instr(i);
lex->sphead->m_has_return= TRUE;
} }
} }
| IF sp_if END IF {} | IF sp_if END IF {}
...@@ -1645,14 +1646,16 @@ sp_unlabeled_control: ...@@ -1645,14 +1646,16 @@ sp_unlabeled_control:
LEX *lex= Lex; LEX *lex= Lex;
sp_head *sp= lex->sphead; sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont; sp_pcontext *ctx= lex->spcont;
sp_instr_hpop *i;
sp->backpatch(ctx->pop_label()); sp->backpatch(ctx->pop_label());
ctx->pop_pvar($3.vars); ctx->pop_pvar($3.vars);
ctx->pop_cond($3.conds); ctx->pop_cond($3.conds);
i= new sp_instr_hpop(sp->instructions(), $3.hndlrs); if ($3.hndlrs)
{
sp_instr_hpop *i= new sp_instr_hpop(sp->instructions(),$3.hndlrs);
sp->add_instr(i); sp->add_instr(i);
} }
}
| LOOP_SYM | LOOP_SYM
sp_proc_stmts END LOOP_SYM sp_proc_stmts END LOOP_SYM
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment