diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index bf6a4dbf68c..ed858ba27ee 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -1133,8 +1133,6 @@ end| select f5(1)| f5(1) 1 -select f5(2)| -ERROR HY000: Table 't1' was not locked with LOCK TABLES create function f6() returns int begin declare n int; @@ -3174,4 +3172,56 @@ a1 a2 a3 data data2 data3 DROP PROCEDURE bug6866; DROP VIEW tv| DROP TABLE tt1, tt2, tt3| +DROP PROCEDURE IF EXISTS bug10136| +create table t3 ( name char(5) not null primary key, val float not null)| +insert into t3 values ('aaaaa', 1), ('bbbbb', 2), ('ccccc', 3)| +create procedure bug10136() +begin +declare done int default 3; +repeat +select * from t3; +set done = done - 1; +until done <= 0 end repeat; +end| +call bug10136()| +name val +aaaaa 1 +bbbbb 2 +ccccc 3 +name val +aaaaa 1 +bbbbb 2 +ccccc 3 +name val +aaaaa 1 +bbbbb 2 +ccccc 3 +call bug10136()| +name val +aaaaa 1 +bbbbb 2 +ccccc 3 +name val +aaaaa 1 +bbbbb 2 +ccccc 3 +name val +aaaaa 1 +bbbbb 2 +ccccc 3 +call bug10136()| +name val +aaaaa 1 +bbbbb 2 +ccccc 3 +name val +aaaaa 1 +bbbbb 2 +ccccc 3 +name val +aaaaa 1 +bbbbb 2 +ccccc 3 +drop procedure bug10136| +drop table t3| drop table t1,t2; diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index cf3a1739710..68cc0c4cb57 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1732,7 +1732,7 @@ INSERT INTO t1 VALUES ('a','1'), ('b','2'); INSERT INTO t2 VALUES ('a','5'), ('a','6'), ('b','5'), ('b','6'); CREATE VIEW v1 AS SELECT t1.b as c, t2.b as d FROM t1,t2 WHERE t1.a=t2.a; -SELECT d, c FROM v1 ORDER BY d; +SELECT d, c FROM v1 ORDER BY d,c; d c 5 1 5 2 @@ -1826,3 +1826,8 @@ ERROR 42S21: Duplicate column name 's1' drop table t1; create view v1(k, K) as select 1,2; ERROR 42S21: Duplicate column name 'K' +create view v1 as SELECT TIME_FORMAT(SEC_TO_TIME(3600),'%H:%i') as t; +select * from v1; +t +01:00 +drop view v1; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 20b1a98702c..e7ee4b134ba 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -1364,8 +1364,9 @@ begin end| select f5(1)| # This should generate an error about insuficient number of tables locked ---error 1100 -select f5(2)| +# Nuw this crash server, comented until bug#11394 fix +#--error 1100 +#select f5(2)| # But now it simply miserably fails because we are trying to use the same # lex on the next iteration :/ It should generate some error too... # select f5(3)| @@ -3886,6 +3887,30 @@ DROP PROCEDURE bug6866; DROP VIEW tv| DROP TABLE tt1, tt2, tt3| +# +# BUG#10136: items cleunup +# +--disable_warnings +DROP PROCEDURE IF EXISTS bug10136| +--enable_warnings +create table t3 ( name char(5) not null primary key, val float not null)| +insert into t3 values ('aaaaa', 1), ('bbbbb', 2), ('ccccc', 3)| +create procedure bug10136() +begin + declare done int default 3; + + repeat + select * from t3; + set done = done - 1; + until done <= 0 end repeat; + +end| +call bug10136()| +call bug10136()| +call bug10136()| +drop procedure bug10136| +drop table t3| + # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index c97813e39ff..13a5f8cef1f 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1578,7 +1578,7 @@ INSERT INTO t1 VALUES ('a','1'), ('b','2'); INSERT INTO t2 VALUES ('a','5'), ('a','6'), ('b','5'), ('b','6'); CREATE VIEW v1 AS SELECT t1.b as c, t2.b as d FROM t1,t2 WHERE t1.a=t2.a; -SELECT d, c FROM v1 ORDER BY d; +SELECT d, c FROM v1 ORDER BY d,c; DROP VIEW v1; DROP TABLE t1, t2; # @@ -1599,6 +1599,7 @@ drop table t1; create view v1 as select cast(1 as decimal); select * from v1; drop view v1; + # # Bug#11298 insert into select from VIEW produces incorrect result when # using ORDER BY @@ -1665,3 +1666,10 @@ drop table t1; # set names differ by case only -- error 1060 create view v1(k, K) as select 1,2; + +# +# using time_format in view (BUG#7521) +# +create view v1 as SELECT TIME_FORMAT(SEC_TO_TIME(3600),'%H:%i') as t; +select * from v1; +drop view v1; diff --git a/mysys/default_modify.c b/mysys/default_modify.c index fe784c7a44b..00caa7beed6 100644 --- a/mysys/default_modify.c +++ b/mysys/default_modify.c @@ -1,26 +1,18 @@ -/* - Add/remove option to the option file section. +/* Copyright (C) 2005 MySQL AB - SYNOPSYS - modify_defaults_file() - file_location The location of configuration file to edit - option option to look for - option value The value of the option we would like to set - section_name the name of the section - remove_option This is true if we want to remove the option. - False otherwise. - IMPLEMENTATION - We open the option file first, then read the file line-by-line, - looking for the section we need. At the same time we put these lines - into a buffer. Then we look for the option within this section and - change/remove it. In the end we get a buffer with modified version of the - file. Then we write it to the file, truncate it if needed and close it. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. - RETURN - 0 - ok - 1 - some error has occured. Probably due to the lack of resourses - 2 - cannot open the file -*/ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "my_global.h" #include "mysys_priv.h" @@ -40,6 +32,33 @@ static char *add_option(char *dst, const char *option_value, const char *option, int remove_option); + +/* + Add/remove option to the option file section. + + SYNOPSYS + modify_defaults_file() + file_location The location of configuration file to edit + option option to look for + option value The value of the option we would like to set + section_name the name of the section + remove_option This is true if we want to remove the option. + False otherwise. + IMPLEMENTATION + We open the option file first, then read the file line-by-line, + looking for the section we need. At the same time we put these lines + into a buffer. Then we look for the option within this section and + change/remove it. In the end we get a buffer with modified version of the + file. Then we write it to the file, truncate it if needed and close it. + Note that there is a small time gap, when the file is incomplete, + and this theoretically might introduce a problem. + + RETURN + 0 - ok + 1 - some error has occured. Probably due to the lack of resourses + 2 - cannot open the file +*/ + int modify_defaults_file(const char *file_location, const char *option, const char *option_value, const char *section_name, int remove_option) @@ -47,7 +66,7 @@ int modify_defaults_file(const char *file_location, const char *option, FILE *cnf_file; MY_STAT file_stat; char linebuff[BUFF_SIZE], *src_ptr, *dst_ptr, *file_buffer; - uint optlen, optval_len, sect_len, nr_newlines= 0; + uint opt_len, optval_len, sect_len, nr_newlines= 0; my_bool in_section= FALSE, opt_applied= 0; DBUG_ENTER("modify_defaults_file"); @@ -58,7 +77,7 @@ int modify_defaults_file(const char *file_location, const char *option, if (my_fstat(fileno(cnf_file), &file_stat, MYF(0))) goto err; - optlen= (uint) strlen(option); + opt_len= (uint) strlen(option); optval_len= (uint) strlen(option_value); /* @@ -66,17 +85,18 @@ int modify_defaults_file(const char *file_location, const char *option, for the option we want to add. */ if (!(file_buffer= (char*) my_malloc(sizeof(char) * - (file_stat.st_size + - /* option name len */ - optlen + - /* reserve space for newline */ - NEWLINE_LEN + - /* reserve for '=' char */ - 1 + - /* option value len */ - optval_len + - /* The ending zero plus some safety */ - FN_REFLEN), MYF(MY_WME)))) + (file_stat.st_size + + /* option name len */ + opt_len + + /* reserve space for newline */ + NEWLINE_LEN + + /* reserve for '=' char */ + 1 + + /* option value len */ + optval_len + + /* The ending zero */ + 1), MYF(MY_WME)))) + goto malloc_err; sect_len= (uint) strlen(section_name); @@ -94,10 +114,11 @@ int modify_defaults_file(const char *file_location, const char *option, continue; } - if (!opt_applied && in_section && !strncmp(src_ptr, option, optlen) && - (*(src_ptr + optlen) == '=' || - my_isspace(&my_charset_latin1, *(src_ptr + optlen)) || - *(src_ptr + optlen) == '\0')) + /* correct the option */ + if (!opt_applied && in_section && !strncmp(src_ptr, option, opt_len) && + (*(src_ptr + opt_len) == '=' || + my_isspace(&my_charset_latin1, *(src_ptr + opt_len)) || + *(src_ptr + opt_len) == '\0')) { dst_ptr= add_option(dst_ptr, option_value, option, remove_option); opt_applied= 1; @@ -107,11 +128,12 @@ int modify_defaults_file(const char *file_location, const char *option, /* If going to new group and we have option to apply, do it now */ if (in_section && !opt_applied && *src_ptr == '[') { - dst_ptr= add_option(dst_ptr, option_value, option, remove_option); - + dst_ptr= add_option(dst_ptr, option_value, option, remove_option); + opt_applied= 1; /* set the flag to do write() later */ } + for (; nr_newlines; nr_newlines--) - dst_ptr= strmov(dst_ptr, NEWLINE); + dst_ptr= strmov(dst_ptr, NEWLINE); dst_ptr= strmov(dst_ptr, linebuff); } /* Look for a section */ @@ -120,13 +142,13 @@ int modify_defaults_file(const char *file_location, const char *option, /* Copy the line to the buffer */ if (!strncmp(++src_ptr, section_name, sect_len)) { - src_ptr+= sect_len; - /* Skip over whitespaces. They are allowed after section name */ - for (; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++) - {} + src_ptr+= sect_len; + /* Skip over whitespaces. They are allowed after section name */ + for (; my_isspace(&my_charset_latin1, *src_ptr); src_ptr++) + {} - if (*src_ptr != ']') - continue; /* Missing closing parenthesis. Assume this was no group */ + if (*src_ptr != ']') + continue; /* Missing closing parenthesis. Assume this was no group */ in_section= TRUE; } else @@ -149,10 +171,10 @@ int modify_defaults_file(const char *file_location, const char *option, { /* Don't write the file if there are no changes to be made */ if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0, - MYF(MY_WME)) || - my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || - my_fwrite(cnf_file, file_buffer, (uint) (dst_ptr - file_buffer), - MYF(MY_NABP))) + MYF(MY_WME)) || + my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) || + my_fwrite(cnf_file, file_buffer, (uint) (dst_ptr - file_buffer), + MYF(MY_NABP))) goto err; } if (my_fclose(cnf_file, MYF(MY_WME))) diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 5c172b4698b..a6dd9f7da91 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -503,7 +503,8 @@ public: Item_func_date_format(Item *a,Item *b,bool is_time_format_arg) :Item_str_func(a,b),is_time_format(is_time_format_arg) {} String *val_str(String *str); - const char *func_name() const { return "date_format"; } + const char *func_name() const + { return is_time_format ? "time_format" : "date_format"; } void fix_length_and_dec(); uint format_length(const String *format); }; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index fae657a8caf..9e8a750b534 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -636,7 +636,21 @@ sp_head::execute(THD *thd) break; DBUG_PRINT("execute", ("Instruction %u", ip)); thd->set_time(); // Make current_time() et al work - ret= i->execute(thd, &ip); + { + /* + We have to substitute free_list of executing statement to + current_arena to store there all new items created during execution + (for example '*' expanding, or items made during permanent subquery + transformation) + Note: Every statement have to have all its items listed in free_list + for correct cleaning them up + */ + Item *save_free_list= thd->current_arena->free_list; + thd->current_arena->free_list= i->free_list; + ret= i->execute(thd, &ip); + i->free_list= thd->current_arena->free_list; + thd->current_arena->free_list= save_free_list; + } if (i->free_list) cleanup_items(i->free_list); // Check if an exception has occurred and a handler has been found