Commit f7295f24 authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into  neptunus.(none):/home/msvensson/mysql/mysql-5.0


mysql-test/r/sp.result:
  Auto merged
mysql-test/t/sp.test:
  Auto merged
parents 9b1aa7fa 2a88d0f4
...@@ -1176,3 +1176,6 @@ end| ...@@ -1176,3 +1176,6 @@ end|
call bug15091(); call bug15091();
ERROR 42S02: Unknown table 'c' in field list ERROR 42S02: Unknown table 'c' in field list
drop procedure bug15091; drop procedure bug15091;
drop function if exists bug16896;
create aggregate function bug16896() returns int return 1;
ERROR 42000: AGGREGATE is not supported for stored functions
...@@ -314,3 +314,12 @@ select * from db_bug14533.t1; ...@@ -314,3 +314,12 @@ select * from db_bug14533.t1;
ERROR 42000: SELECT command denied to user 'user_bug14533'@'localhost' for table 't1' ERROR 42000: SELECT command denied to user 'user_bug14533'@'localhost' for table 't1'
drop user user_bug14533@localhost; drop user user_bug14533@localhost;
drop database db_bug14533; drop database db_bug14533;
CREATE DATABASE db_bug7787;
use db_bug7787;
CREATE PROCEDURE p1()
SHOW INNODB STATUS;
Warnings:
Warning 1287 'SHOW INNODB STATUS' is deprecated; use 'SHOW ENGINE INNODB STATUS' instead
GRANT EXECUTE ON PROCEDURE p1 TO user_bug7787@localhost;
DROP DATABASE db_bug7787;
use test;
...@@ -1413,8 +1413,6 @@ select `foo` ()| ...@@ -1413,8 +1413,6 @@ select `foo` ()|
5 5
drop function `foo`| drop function `foo`|
drop function if exists t1max| drop function if exists t1max|
Warnings:
Note 1305 FUNCTION t1max does not exist
create function t1max() returns int create function t1max() returns int
begin begin
declare x int; declare x int;
...@@ -1470,6 +1468,339 @@ zip 3 ...@@ -1470,6 +1468,339 @@ zip 3
foo 1 foo 1
drop table t3| drop table t3|
drop function getcount| drop function getcount|
drop table if exists t3|
drop procedure if exists h_ee|
drop procedure if exists h_es|
drop procedure if exists h_en|
drop procedure if exists h_ew|
drop procedure if exists h_ex|
drop procedure if exists h_se|
drop procedure if exists h_ss|
drop procedure if exists h_sn|
drop procedure if exists h_sw|
drop procedure if exists h_sx|
drop procedure if exists h_ne|
drop procedure if exists h_ns|
drop procedure if exists h_nn|
drop procedure if exists h_we|
drop procedure if exists h_ws|
drop procedure if exists h_ww|
drop procedure if exists h_xe|
drop procedure if exists h_xs|
drop procedure if exists h_xx|
create table t3 (a smallint primary key)|
insert into t3 (a) values (1)|
create procedure h_ee()
deterministic
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Outer (bad)' as 'h_ee';
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Inner (good)' as 'h_ee';
insert into t3 values (1);
end;
end|
create procedure h_es()
deterministic
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Outer (good)' as 'h_es';
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Inner (bad)' as 'h_es';
insert into t3 values (1);
end;
end|
create procedure h_en()
deterministic
begin
declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
select 'Outer (good)' as 'h_en';
begin
declare x int;
declare continue handler for sqlstate '02000' -- no data
select 'Inner (bad)' as 'h_en';
select a into x from t3 where a = 42;
end;
end|
create procedure h_ew()
deterministic
begin
declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
select 'Outer (good)' as 'h_ew';
begin
declare continue handler for sqlwarning
select 'Inner (bad)' as 'h_ew';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_ex()
deterministic
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Outer (good)' as 'h_ex';
begin
declare continue handler for sqlexception
select 'Inner (bad)' as 'h_ex';
insert into t3 values (1);
end;
end|
create procedure h_se()
deterministic
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Outer (bad)' as 'h_se';
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Inner (good)' as 'h_se';
insert into t3 values (1);
end;
end|
create procedure h_ss()
deterministic
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Outer (bad)' as 'h_ss';
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Inner (good)' as 'h_ss';
insert into t3 values (1);
end;
end|
create procedure h_sn()
deterministic
begin
-- Note: '02000' is more specific than NOT FOUND ;
-- there might be other not found states
declare continue handler for sqlstate '02000' -- no data
select 'Outer (good)' as 'h_sn';
begin
declare x int;
declare continue handler for not found
select 'Inner (bad)' as 'h_sn';
select a into x from t3 where a = 42;
end;
end|
create procedure h_sw()
deterministic
begin
-- data exception - numeric value out of range
declare continue handler for sqlstate '22003'
select 'Outer (good)' as 'h_sw';
begin
declare continue handler for sqlwarning
select 'Inner (bad)' as 'h_sw';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_sx()
deterministic
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Outer (good)' as 'h_sx';
begin
declare continue handler for sqlexception
select 'Inner (bad)' as 'h_sx';
insert into t3 values (1);
end;
end|
create procedure h_ne()
deterministic
begin
declare continue handler for not found
select 'Outer (bad)' as 'h_ne';
begin
declare x int;
declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
select 'Inner (good)' as 'h_ne';
select a into x from t3 where a = 42;
end;
end|
create procedure h_ns()
deterministic
begin
declare continue handler for not found
select 'Outer (bad)' as 'h_ns';
begin
declare x int;
declare continue handler for sqlstate '02000' -- no data
select 'Inner (good)' as 'h_ns';
select a into x from t3 where a = 42;
end;
end|
create procedure h_nn()
deterministic
begin
declare continue handler for not found
select 'Outer (bad)' as 'h_nn';
begin
declare x int;
declare continue handler for not found
select 'Inner (good)' as 'h_nn';
select a into x from t3 where a = 42;
end;
end|
create procedure h_we()
deterministic
begin
declare continue handler for sqlwarning
select 'Outer (bad)' as 'h_we';
begin
declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
select 'Inner (good)' as 'h_we';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_ws()
deterministic
begin
declare continue handler for sqlwarning
select 'Outer (bad)' as 'h_ws';
begin
-- data exception - numeric value out of range
declare continue handler for sqlstate '22003'
select 'Inner (good)' as 'h_ws';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_ww()
deterministic
begin
declare continue handler for sqlwarning
select 'Outer (bad)' as 'h_ww';
begin
declare continue handler for sqlwarning
select 'Inner (good)' as 'h_ww';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_xe()
deterministic
begin
declare continue handler for sqlexception
select 'Outer (bad)' as 'h_xe';
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Inner (good)' as 'h_xe';
insert into t3 values (1);
end;
end|
create procedure h_xs()
deterministic
begin
declare continue handler for sqlexception
select 'Outer (bad)' as 'h_xs';
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Inner (good)' as 'h_xs';
insert into t3 values (1);
end;
end|
create procedure h_xx()
deterministic
begin
declare continue handler for sqlexception
select 'Outer (bad)' as 'h_xx';
begin
declare continue handler for sqlexception
select 'Inner (good)' as 'h_xx';
insert into t3 values (1);
end;
end|
call h_ee()|
h_ee
Inner (good)
call h_es()|
h_es
Outer (good)
call h_en()|
h_en
Outer (good)
call h_ew()|
h_ew
Outer (good)
call h_ex()|
h_ex
Outer (good)
call h_se()|
h_se
Inner (good)
call h_ss()|
h_ss
Inner (good)
call h_sn()|
h_sn
Outer (good)
call h_sw()|
h_sw
Outer (good)
call h_sx()|
h_sx
Outer (good)
call h_ne()|
h_ne
Inner (good)
call h_ns()|
h_ns
Inner (good)
call h_nn()|
h_nn
Inner (good)
call h_we()|
h_we
Inner (good)
call h_ws()|
h_ws
Inner (good)
call h_ww()|
h_ww
Inner (good)
call h_xe()|
h_xe
Inner (good)
call h_xs()|
h_xs
Inner (good)
call h_xx()|
h_xx
Inner (good)
drop table t3|
drop procedure h_ee|
drop procedure h_es|
drop procedure h_en|
drop procedure h_ew|
drop procedure h_ex|
drop procedure h_se|
drop procedure h_ss|
drop procedure h_sn|
drop procedure h_sw|
drop procedure h_sx|
drop procedure h_ne|
drop procedure h_ns|
drop procedure h_nn|
drop procedure h_we|
drop procedure h_ws|
drop procedure h_ww|
drop procedure h_xe|
drop procedure h_xs|
drop procedure h_xx|
drop procedure if exists bug822| drop procedure if exists bug822|
create procedure bug822(a_id char(16), a_data int) create procedure bug822(a_id char(16), a_data int)
begin begin
......
...@@ -1703,6 +1703,17 @@ call bug15091(); ...@@ -1703,6 +1703,17 @@ call bug15091();
drop procedure bug15091; drop procedure bug15091;
#
# BUG#16896: Stored function: unused AGGREGATE-clause in CREATE FUNCTION
#
--disable_warnings
drop function if exists bug16896;
--enable_warnings
--error ER_SP_NO_AGGREGATE
create aggregate function bug16896() returns int return 1;
# #
# BUG#NNNN: New bug synopsis # BUG#NNNN: New bug synopsis
# #
...@@ -1710,3 +1721,4 @@ drop procedure bug15091; ...@@ -1710,3 +1721,4 @@ drop procedure bug15091;
#drop procedure if exists bugNNNN| #drop procedure if exists bugNNNN|
#--enable_warnings #--enable_warnings
#create procedure bugNNNN... #create procedure bugNNNN...
...@@ -525,4 +525,26 @@ disconnect user_bug14533; ...@@ -525,4 +525,26 @@ disconnect user_bug14533;
drop user user_bug14533@localhost; drop user user_bug14533@localhost;
drop database db_bug14533; drop database db_bug14533;
#
# BUG#7787: Stored procedures: improper warning for "grant execute" statement
#
# Prepare.
CREATE DATABASE db_bug7787;
use db_bug7787;
# Test.
CREATE PROCEDURE p1()
SHOW INNODB STATUS;
GRANT EXECUTE ON PROCEDURE p1 TO user_bug7787@localhost;
# Cleanup.
DROP DATABASE db_bug7787;
use test;
# End of 5.0 bugs. # End of 5.0 bugs.
...@@ -1660,7 +1660,7 @@ drop function `foo`| ...@@ -1660,7 +1660,7 @@ drop function `foo`|
# Implicit LOCK/UNLOCK TABLES for table access in functions # Implicit LOCK/UNLOCK TABLES for table access in functions
# #
--disable_warning --disable_warnings
drop function if exists t1max| drop function if exists t1max|
--enable_warnings --enable_warnings
create function t1max() returns int create function t1max() returns int
...@@ -1704,6 +1704,397 @@ drop table t3| ...@@ -1704,6 +1704,397 @@ drop table t3|
drop function getcount| drop function getcount|
# Test cases for different combinations of condition handlers in nested
# begin-end blocks in stored procedures.
#
# Note that the standard specifies that the most specific handler should
# be triggered even if it's an outer handler masked by a less specific
# handler in an inner block.
# Note also that '02000' is more specific than NOT FOUND; there might be
# other '02xxx' states, even if we currently do not issue them in any
# situation (e.g. '02001').
#
# The combinations we test are these:
#
# Inner
# errcode sqlstate not found sqlwarning sqlexception
# Outer +------------+------------+------------+------------+------------+
#errcode | h_ee (i) | h_es (o) | h_en (o) | h_ew (o) | h_ex (o) |
#sqlstate | h_se (i) | h_ss (i) | h_sn (o) | h_sw (o) | h_sx (o) |
#not found | h_ne (i) | h_ns (i) | h_nn (i) | | |
#sqlwarning | h_we (i) | h_ws (i) | | h_ww (i) | |
#sqlexception | h_xe (i) | h_xs (i) | | | h_xx (i) |
# +------------+---------------------------------------------------+
#
# (i) means that the inner handler is the one that should be invoked,
# (o) means that the outer handler should be invoked.
#
# ('not found', 'sqlwarning' and 'sqlexception' are mutually exclusive, hence
# no tests for those combinations.)
#
--disable_warnings
drop table if exists t3|
drop procedure if exists h_ee|
drop procedure if exists h_es|
drop procedure if exists h_en|
drop procedure if exists h_ew|
drop procedure if exists h_ex|
drop procedure if exists h_se|
drop procedure if exists h_ss|
drop procedure if exists h_sn|
drop procedure if exists h_sw|
drop procedure if exists h_sx|
drop procedure if exists h_ne|
drop procedure if exists h_ns|
drop procedure if exists h_nn|
drop procedure if exists h_we|
drop procedure if exists h_ws|
drop procedure if exists h_ww|
drop procedure if exists h_xe|
drop procedure if exists h_xs|
drop procedure if exists h_xx|
--enable_warnings
# smallint - to get out of range warnings
# primary key - to get constraint errors
create table t3 (a smallint primary key)|
insert into t3 (a) values (1)|
create procedure h_ee()
deterministic
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Outer (bad)' as 'h_ee';
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Inner (good)' as 'h_ee';
insert into t3 values (1);
end;
end|
create procedure h_es()
deterministic
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Outer (good)' as 'h_es';
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Inner (bad)' as 'h_es';
insert into t3 values (1);
end;
end|
create procedure h_en()
deterministic
begin
declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
select 'Outer (good)' as 'h_en';
begin
declare x int;
declare continue handler for sqlstate '02000' -- no data
select 'Inner (bad)' as 'h_en';
select a into x from t3 where a = 42;
end;
end|
create procedure h_ew()
deterministic
begin
declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
select 'Outer (good)' as 'h_ew';
begin
declare continue handler for sqlwarning
select 'Inner (bad)' as 'h_ew';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_ex()
deterministic
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Outer (good)' as 'h_ex';
begin
declare continue handler for sqlexception
select 'Inner (bad)' as 'h_ex';
insert into t3 values (1);
end;
end|
create procedure h_se()
deterministic
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Outer (bad)' as 'h_se';
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Inner (good)' as 'h_se';
insert into t3 values (1);
end;
end|
create procedure h_ss()
deterministic
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Outer (bad)' as 'h_ss';
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Inner (good)' as 'h_ss';
insert into t3 values (1);
end;
end|
create procedure h_sn()
deterministic
begin
-- Note: '02000' is more specific than NOT FOUND ;
-- there might be other not found states
declare continue handler for sqlstate '02000' -- no data
select 'Outer (good)' as 'h_sn';
begin
declare x int;
declare continue handler for not found
select 'Inner (bad)' as 'h_sn';
select a into x from t3 where a = 42;
end;
end|
create procedure h_sw()
deterministic
begin
-- data exception - numeric value out of range
declare continue handler for sqlstate '22003'
select 'Outer (good)' as 'h_sw';
begin
declare continue handler for sqlwarning
select 'Inner (bad)' as 'h_sw';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_sx()
deterministic
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Outer (good)' as 'h_sx';
begin
declare continue handler for sqlexception
select 'Inner (bad)' as 'h_sx';
insert into t3 values (1);
end;
end|
create procedure h_ne()
deterministic
begin
declare continue handler for not found
select 'Outer (bad)' as 'h_ne';
begin
declare x int;
declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
select 'Inner (good)' as 'h_ne';
select a into x from t3 where a = 42;
end;
end|
create procedure h_ns()
deterministic
begin
declare continue handler for not found
select 'Outer (bad)' as 'h_ns';
begin
declare x int;
declare continue handler for sqlstate '02000' -- no data
select 'Inner (good)' as 'h_ns';
select a into x from t3 where a = 42;
end;
end|
create procedure h_nn()
deterministic
begin
declare continue handler for not found
select 'Outer (bad)' as 'h_nn';
begin
declare x int;
declare continue handler for not found
select 'Inner (good)' as 'h_nn';
select a into x from t3 where a = 42;
end;
end|
create procedure h_we()
deterministic
begin
declare continue handler for sqlwarning
select 'Outer (bad)' as 'h_we';
begin
declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
select 'Inner (good)' as 'h_we';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_ws()
deterministic
begin
declare continue handler for sqlwarning
select 'Outer (bad)' as 'h_ws';
begin
-- data exception - numeric value out of range
declare continue handler for sqlstate '22003'
select 'Inner (good)' as 'h_ws';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_ww()
deterministic
begin
declare continue handler for sqlwarning
select 'Outer (bad)' as 'h_ww';
begin
declare continue handler for sqlwarning
select 'Inner (good)' as 'h_ww';
insert into t3 values (123456789012);
end;
delete from t3;
insert into t3 values (1);
end|
create procedure h_xe()
deterministic
begin
declare continue handler for sqlexception
select 'Outer (bad)' as 'h_xe';
begin
declare continue handler for 1062 -- ER_DUP_ENTRY
select 'Inner (good)' as 'h_xe';
insert into t3 values (1);
end;
end|
create procedure h_xs()
deterministic
begin
declare continue handler for sqlexception
select 'Outer (bad)' as 'h_xs';
begin
-- integrity constraint violation
declare continue handler for sqlstate '23000'
select 'Inner (good)' as 'h_xs';
insert into t3 values (1);
end;
end|
create procedure h_xx()
deterministic
begin
declare continue handler for sqlexception
select 'Outer (bad)' as 'h_xx';
begin
declare continue handler for sqlexception
select 'Inner (good)' as 'h_xx';
insert into t3 values (1);
end;
end|
call h_ee()|
call h_es()|
call h_en()|
call h_ew()|
call h_ex()|
call h_se()|
call h_ss()|
call h_sn()|
call h_sw()|
call h_sx()|
call h_ne()|
call h_ns()|
call h_nn()|
call h_we()|
call h_ws()|
call h_ww()|
call h_xe()|
call h_xs()|
call h_xx()|
drop table t3|
drop procedure h_ee|
drop procedure h_es|
drop procedure h_en|
drop procedure h_ew|
drop procedure h_ex|
drop procedure h_se|
drop procedure h_ss|
drop procedure h_sn|
drop procedure h_sw|
drop procedure h_sx|
drop procedure h_ne|
drop procedure h_ns|
drop procedure h_nn|
drop procedure h_we|
drop procedure h_ws|
drop procedure h_ww|
drop procedure h_xe|
drop procedure h_xs|
drop procedure h_xx|
# #
# Test cases for old bugs # Test cases for old bugs
# #
......
...@@ -5116,9 +5116,9 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const ...@@ -5116,9 +5116,9 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
if (item_ref->ref_type() == VIEW_REF) if (item_ref->ref_type() == VIEW_REF)
{ {
Item *item_ref_ref= *(item_ref->ref); Item *item_ref_ref= *(item_ref->ref);
DBUG_ASSERT((*ref)->type() == FIELD_ITEM && DBUG_ASSERT((*ref)->real_item()->type() == FIELD_ITEM &&
(item_ref_ref->type() == FIELD_ITEM)); (item_ref_ref->real_item()->type() == FIELD_ITEM));
return (*ref == item_ref_ref); return ((*ref)->real_item() == item_ref_ref->real_item());
} }
} }
return FALSE; return FALSE;
......
...@@ -981,7 +981,7 @@ void free_io_cache(TABLE *entry); ...@@ -981,7 +981,7 @@ void free_io_cache(TABLE *entry);
void intern_close_table(TABLE *entry); void intern_close_table(TABLE *entry);
bool close_thread_table(THD *thd, TABLE **table_ptr); bool close_thread_table(THD *thd, TABLE **table_ptr);
void close_temporary_tables(THD *thd); void close_temporary_tables(THD *thd);
void close_tables_for_reopen(THD *thd, TABLE_LIST *tables); void close_tables_for_reopen(THD *thd, TABLE_LIST **tables);
TABLE_LIST *find_table_in_list(TABLE_LIST *table, TABLE_LIST *find_table_in_list(TABLE_LIST *table,
uint offset_to_list, uint offset_to_list,
const char *db_name, const char *db_name,
......
...@@ -5609,3 +5609,5 @@ ER_SP_WRONG_NAME 42000 ...@@ -5609,3 +5609,5 @@ ER_SP_WRONG_NAME 42000
eng "Incorrect routine name '%-.64s'" eng "Incorrect routine name '%-.64s'"
ER_TABLE_NEEDS_UPGRADE ER_TABLE_NEEDS_UPGRADE
eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!" eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!"
ER_SP_NO_AGGREGATE 42000
eng "AGGREGATE is not supported for stored functions"
...@@ -1012,6 +1012,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error) ...@@ -1012,6 +1012,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
{ {
TABLE_LIST *routine; TABLE_LIST *routine;
bool result= 0; bool result= 0;
bool sp_object_found;
DBUG_ENTER("sp_exists_routine"); DBUG_ENTER("sp_exists_routine");
for (routine= routines; routine; routine= routine->next_global) for (routine= routines; routine; routine= routine->next_global)
{ {
...@@ -1024,10 +1025,12 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error) ...@@ -1024,10 +1025,12 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
lex_name.str= thd->strmake(routine->table_name, lex_name.length); lex_name.str= thd->strmake(routine->table_name, lex_name.length);
name= new sp_name(lex_db, lex_name); name= new sp_name(lex_db, lex_name);
name->init_qname(thd); name->init_qname(thd);
if (sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name, sp_object_found= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
&thd->sp_proc_cache, FALSE) != NULL || &thd->sp_proc_cache, FALSE) != NULL ||
sp_find_routine(thd, TYPE_ENUM_FUNCTION, name, sp_find_routine(thd, TYPE_ENUM_FUNCTION, name,
&thd->sp_func_cache, FALSE) != NULL) &thd->sp_func_cache, FALSE) != NULL;
mysql_reset_errors(thd, TRUE);
if (sp_object_found)
{ {
if (any) if (any)
DBUG_RETURN(1); DBUG_RETURN(1);
......
...@@ -1982,22 +1982,11 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) ...@@ -1982,22 +1982,11 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
statement for which table list for prelocking is already built, let statement for which table list for prelocking is already built, let
us cache routines and try to build such table list. us cache routines and try to build such table list.
NOTE: We can't delay prelocking until we will met some sub-statement
which really uses tables, since this will imply that we have to restore
its table list to be able execute it in some other context.
And current views implementation assumes that view tables are added to
global table list only once during PS preparing/first SP execution.
Also locking at earlier stage is probably faster altough may decrease
concurrency a bit.
NOTE: We will mark statement as requiring prelocking only if we will NOTE: We will mark statement as requiring prelocking only if we will
have non empty table list. But this does not guarantee that in prelocked have non empty table list. But this does not guarantee that in prelocked
mode we will have some locked tables, because queries which use only mode we will have some locked tables, because queries which use only
derived/information schema tables and views possible. Thus "counter" derived/information schema tables and views possible. Thus "counter"
may be still zero for prelocked statement... may be still zero for prelocked statement...
NOTE: The above notes may be out of date. Please wait for psergey to
document new prelocked behavior.
*/ */
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() && if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
...@@ -2083,48 +2072,23 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) ...@@ -2083,48 +2072,23 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
if (refresh) // Refresh in progress if (refresh) // Refresh in progress
{ {
/* close all 'old' tables used by this thread */
pthread_mutex_lock(&LOCK_open);
// if query_id is not reset, we will get an error
// re-opening a temp table
thd->version=refresh_version;
TABLE **prev_table= &thd->open_tables;
bool found=0;
for (TABLE_LIST *tmp= *start; tmp; tmp= tmp->next_global)
{
/* Close normal (not temporary) changed tables */
if (tmp->table && ! tmp->table->s->tmp_table)
{
if (tmp->table->s->version != refresh_version ||
! tmp->table->db_stat)
{
VOID(hash_delete(&open_cache,(byte*) tmp->table));
tmp->table=0;
found=1;
}
else
{
*prev_table= tmp->table; // Relink open list
prev_table= &tmp->table->next;
}
}
}
*prev_table=0;
pthread_mutex_unlock(&LOCK_open);
if (found)
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
/* /*
Let us prepare for recalculation of set of prelocked tables. We have met name-locked or old version of table. Now we have
First we pretend that we have finished calculation which we to close all tables which are not up to date. We also have to
were doing currently. Then we restore list of tables to be throw away set of prelocked tables (and thus close tables from
opened and set of used routines to the state in which they were this set that were open by now) since it possible that one of
before first open_tables() call for this statement (i.e. before tables which determined its content was changed.
we have calculated current set of tables for prelocking).
Instead of implementing complex/non-robust logic mentioned
above we simply close and then reopen all tables.
In order to prepare for recalculation of set of prelocked tables
we pretend that we have finished calculation which we were doing
currently.
*/ */
if (query_tables_last_own) if (query_tables_last_own)
thd->lex->mark_as_requiring_prelocking(query_tables_last_own); thd->lex->mark_as_requiring_prelocking(query_tables_last_own);
thd->lex->chop_off_not_own_tables(); close_tables_for_reopen(thd, start);
sp_remove_not_own_routines(thd->lex);
goto restart; goto restart;
} }
result= -1; // Fatal error result= -1; // Fatal error
...@@ -2335,7 +2299,7 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) ...@@ -2335,7 +2299,7 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
break; break;
if (!need_reopen) if (!need_reopen)
DBUG_RETURN(-1); DBUG_RETURN(-1);
close_tables_for_reopen(thd, tables); close_tables_for_reopen(thd, &tables);
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -2372,7 +2336,7 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) ...@@ -2372,7 +2336,7 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
break; break;
if (!need_reopen) if (!need_reopen)
DBUG_RETURN(-1); DBUG_RETURN(-1);
close_tables_for_reopen(thd, tables); close_tables_for_reopen(thd, &tables);
} }
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) || if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
(thd->fill_derived_tables() && (thd->fill_derived_tables() &&
...@@ -2600,18 +2564,24 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen) ...@@ -2600,18 +2564,24 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
SYNOPSIS SYNOPSIS
close_tables_for_reopen() close_tables_for_reopen()
thd Thread context thd in Thread context
tables List of tables which we were trying to open and lock tables in/out List of tables which we were trying to open and lock
*/ */
void close_tables_for_reopen(THD *thd, TABLE_LIST *tables) void close_tables_for_reopen(THD *thd, TABLE_LIST **tables)
{ {
/*
If table list consists only from tables from prelocking set, table list
for new attempt should be empty, so we have to update list's root pointer.
*/
if (thd->lex->first_not_own_table() == *tables)
*tables= 0;
thd->lex->chop_off_not_own_tables(); thd->lex->chop_off_not_own_tables();
sp_remove_not_own_routines(thd->lex); sp_remove_not_own_routines(thd->lex);
for (TABLE_LIST *tmp= tables; tmp; tmp= tmp->next_global) for (TABLE_LIST *tmp= *tables; tmp; tmp= tmp->next_global)
if (tmp->table && !tmp->table->s->tmp_table)
tmp->table= 0; tmp->table= 0;
mark_used_tables_as_free_for_reuse(thd, thd->temporary_tables);
close_thread_tables(thd); close_thread_tables(thd);
} }
......
...@@ -1135,7 +1135,7 @@ static int mysql_test_update(Prepared_statement *stmt, ...@@ -1135,7 +1135,7 @@ static int mysql_test_update(Prepared_statement *stmt,
break; break;
if (!need_reopen) if (!need_reopen)
goto error; goto error;
close_tables_for_reopen(thd, table_list); close_tables_for_reopen(thd, &table_list);
} }
/* /*
......
...@@ -158,7 +158,7 @@ int mysql_update(THD *thd, ...@@ -158,7 +158,7 @@ int mysql_update(THD *thd,
break; break;
if (!need_reopen) if (!need_reopen)
DBUG_RETURN(1); DBUG_RETURN(1);
close_tables_for_reopen(thd, table_list); close_tables_for_reopen(thd, &table_list);
} }
if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) || if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
...@@ -823,7 +823,7 @@ reopen_tables: ...@@ -823,7 +823,7 @@ reopen_tables:
for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global) for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
tbl->cleanup_items(); tbl->cleanup_items();
close_tables_for_reopen(thd, table_list); close_tables_for_reopen(thd, &table_list);
goto reopen_tables; goto reopen_tables;
} }
......
...@@ -1327,6 +1327,16 @@ create_function_tail: ...@@ -1327,6 +1327,16 @@ create_function_tail:
LEX *lex= Lex; LEX *lex= Lex;
sp_head *sp; sp_head *sp;
/*
First check if AGGREGATE was used, in that case it's a
syntax error.
*/
if (lex->udf.type == UDFTYPE_AGGREGATE)
{
my_error(ER_SP_NO_AGGREGATE, MYF(0));
YYABORT;
}
if (lex->sphead) if (lex->sphead)
{ {
my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION"); my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
......
...@@ -144,6 +144,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result, ...@@ -144,6 +144,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
my_bool myfunc_double_init(UDF_INIT *, UDF_ARGS *args, char *message); my_bool myfunc_double_init(UDF_INIT *, UDF_ARGS *args, char *message);
double myfunc_double(UDF_INIT *initid, UDF_ARGS *args, char *is_null, double myfunc_double(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
char *error); char *error);
my_bool myfunc_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
char *error); char *error);
my_bool sequence_init(UDF_INIT *initid, UDF_ARGS *args, char *message); my_bool sequence_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
...@@ -597,6 +598,14 @@ longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null, ...@@ -597,6 +598,14 @@ longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
return val; return val;
} }
/*
At least one of _init/_deinit is needed unless the server is started
with --allow_suspicious_udfs.
*/
my_bool myfunc_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
return 0;
}
/* /*
Simple example of how to get a sequences starting from the first argument Simple example of how to get a sequences starting from the first argument
......
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