diff options
author | unknown <konstantin@mysql.com> | 2006-02-22 01:20:47 +0300 |
---|---|---|
committer | unknown <konstantin@mysql.com> | 2006-02-22 01:20:47 +0300 |
commit | b56d453c8dd28e3499ed161355fc40d8746012aa (patch) | |
tree | caf9c9e7f64bfa56fff363dc05ff3ebb76ec4b24 | |
parent | 387ae4abcf2d484aebe9eae6edcab81c8c9556f9 (diff) | |
parent | 50c1d251e80e10d0f79967f3437601f6fe0d95af (diff) | |
download | mariadb-git-b56d453c8dd28e3499ed161355fc40d8746012aa.tar.gz |
Merge bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/opt/local/work/mysql-5.0-runtime
sql/sql_yacc.yy:
Auto merged
sql/share/errmsg.txt:
SCCS merged
-rw-r--r-- | mysql-test/r/sp-error.result | 3 | ||||
-rw-r--r-- | mysql-test/r/sp.result | 335 | ||||
-rw-r--r-- | mysql-test/t/sp-error.test | 12 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 393 | ||||
-rw-r--r-- | sql/mysql_priv.h | 2 | ||||
-rw-r--r-- | sql/share/errmsg.txt | 2 | ||||
-rw-r--r-- | sql/sql_base.cc | 84 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 2 | ||||
-rw-r--r-- | sql/sql_update.cc | 4 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 10 | ||||
-rw-r--r-- | sql/udf_example.cc | 9 |
11 files changed, 792 insertions, 64 deletions
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 2766dca5845..c0e02cbeb6f 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1176,3 +1176,6 @@ end| call bug15091(); ERROR 42S02: Unknown table 'c' in field list 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 diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index bec2f049bc4..61c977f1a5c 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -1413,8 +1413,6 @@ select `foo` ()| 5 drop function `foo`| drop function if exists t1max| -Warnings: -Note 1305 FUNCTION t1max does not exist create function t1max() returns int begin declare x int; @@ -1470,6 +1468,339 @@ zip 3 foo 1 drop table t3| 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| create procedure bug822(a_id char(16), a_data int) begin diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index e1839b4b98f..c4745537de3 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -1704,9 +1704,21 @@ 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 # #--disable_warnings #drop procedure if exists bugNNNN| #--enable_warnings #create procedure bugNNNN... + diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 53c15ffd05b..bc0b6f654b8 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -1660,7 +1660,7 @@ drop function `foo`| # Implicit LOCK/UNLOCK TABLES for table access in functions # ---disable_warning +--disable_warnings drop function if exists t1max| --enable_warnings create function t1max() returns int @@ -1704,6 +1704,397 @@ drop table t3| 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 # diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index ca2cda0f7c6..6908f2b9049 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -981,7 +981,7 @@ void free_io_cache(TABLE *entry); void intern_close_table(TABLE *entry); bool close_thread_table(THD *thd, TABLE **table_ptr); 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, uint offset_to_list, const char *db_name, diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 378e205b29a..a860796f02d 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5609,3 +5609,5 @@ ER_SP_WRONG_NAME 42000 eng "Incorrect routine name '%-.64s'" ER_TABLE_NEEDS_UPGRADE 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" diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 9d1720cc527..37d4c80a0d0 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -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 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 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 derived/information schema tables and views possible. Thus "counter" 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() && @@ -2083,48 +2072,23 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) 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. - First we pretend that we have finished calculation which we - were doing currently. Then we restore list of tables to be - opened and set of used routines to the state in which they were - before first open_tables() call for this statement (i.e. before - we have calculated current set of tables for prelocking). + We have met name-locked or old version of table. Now we have + to close all tables which are not up to date. We also have to + throw away set of prelocked tables (and thus close tables from + this set that were open by now) since it possible that one of + tables which determined its content was changed. + + 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) thd->lex->mark_as_requiring_prelocking(query_tables_last_own); - thd->lex->chop_off_not_own_tables(); - sp_remove_not_own_routines(thd->lex); + close_tables_for_reopen(thd, start); goto restart; } result= -1; // Fatal error @@ -2335,7 +2299,7 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables) break; if (!need_reopen) DBUG_RETURN(-1); - close_tables_for_reopen(thd, tables); + close_tables_for_reopen(thd, &tables); } DBUG_RETURN(0); } @@ -2372,7 +2336,7 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables) break; if (!need_reopen) DBUG_RETURN(-1); - close_tables_for_reopen(thd, tables); + close_tables_for_reopen(thd, &tables); } if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) || (thd->fill_derived_tables() && @@ -2600,18 +2564,24 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen) SYNOPSIS close_tables_for_reopen() - thd Thread context - tables List of tables which we were trying to open and lock + thd in Thread context + 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(); sp_remove_not_own_routines(thd->lex); - for (TABLE_LIST *tmp= tables; tmp; tmp= tmp->next_global) - if (tmp->table && !tmp->table->s->tmp_table) - tmp->table= 0; + for (TABLE_LIST *tmp= *tables; tmp; tmp= tmp->next_global) + tmp->table= 0; + mark_used_tables_as_free_for_reuse(thd, thd->temporary_tables); close_thread_tables(thd); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index fbc767688b8..5746e2a6f1a 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1135,7 +1135,7 @@ static int mysql_test_update(Prepared_statement *stmt, break; if (!need_reopen) goto error; - close_tables_for_reopen(thd, table_list); + close_tables_for_reopen(thd, &table_list); } /* diff --git a/sql/sql_update.cc b/sql/sql_update.cc index d319167b61d..f6bc1461842 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -158,7 +158,7 @@ int mysql_update(THD *thd, break; if (!need_reopen) 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) || @@ -823,7 +823,7 @@ reopen_tables: for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global) tbl->cleanup_items(); - close_tables_for_reopen(thd, table_list); + close_tables_for_reopen(thd, &table_list); goto reopen_tables; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3a269a3349b..97410333c48 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1327,6 +1327,16 @@ create_function_tail: LEX *lex= Lex; 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) { my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION"); diff --git a/sql/udf_example.cc b/sql/udf_example.cc index a186b4fbf6c..35833e63fab 100644 --- a/sql/udf_example.cc +++ b/sql/udf_example.cc @@ -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); double myfunc_double(UDF_INIT *initid, UDF_ARGS *args, char *is_null, 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, char *error); 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, 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 |