From 5640d19432952604e29952ee0fbbce85749e3568 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Wed, 5 Oct 2005 16:39:37 +0200 Subject: [PATCH 01/13] Fixed BUG#13616: "CALL ." executes properly, but displays error When returning to the old database (which may be ""), don't do access check - mysql_change_db() would then generate the error "No database selected". Note: No test case added; it seems a db is always selected when running tests. --- sql/sp_head.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 671acbc2a0c..95e050a5ac7 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1051,8 +1051,10 @@ int sp_head::execute(THD *thd) original thd->db will then have been freed */ if (dbchanged) { + /* No access check when changing back to where we came from. + (It would generate an error from mysql_change_db() when olddb=="") */ if (! thd->killed) - ret= mysql_change_db(thd, olddb, 0); + ret= mysql_change_db(thd, olddb, 1); } m_flags&= ~IS_INVOKED; DBUG_RETURN(ret); From 78e828d32f4c94a7135b7ddcf749ddc9e5bd0d3d Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Thu, 6 Oct 2005 17:54:43 +0300 Subject: [PATCH 02/13] Review of code pushed since last 5.0 pull: Ensure that ccache is also used for C programs mysql: Ensure that 'delimiter' works the same way in batch mode as in normal mode mysqldump: Change to use ;; (instead of //) as a stored procedure/trigger delimiter Fixed test cases by adding missing DROP's and rename views to be of type 'v#' Removed MY_UNIX_PATH from fn_format() Removed current_db_used from TABLE_LIST Removed usage of 'current_thd' in Item_splocal Removed some compiler warnings A bit faster longlong2str code --- BUILD/FINISH.sh | 2 +- BUILD/SETUP.sh | 4 + client/mysql.cc | 76 +++++++---- client/mysqldump.c | 59 +++++---- client/mysqltest.c | 8 +- include/my_sys.h | 1 - mysql-test/r/alter_table.result | 10 +- mysql-test/r/func_str.result | 3 + mysql-test/r/information_schema.result | 23 ++-- mysql-test/r/information_schema_inno.result | 2 +- mysql-test/r/multi_statement.result | 1 + mysql-test/r/mysql.result | 1 + mysql-test/r/mysqldump.result | 70 +++++----- mysql-test/r/mysqlshow.result | 1 + mysql-test/r/temp_table.result | 29 +++-- mysql-test/t/alter_table.test | 10 +- mysql-test/t/func_str.test | 1 + mysql-test/t/information_schema.test | 11 +- mysql-test/t/information_schema_inno.test | 2 +- mysql-test/t/multi_statement.test | 4 + mysql-test/t/mysql.test | 2 +- mysql-test/t/mysqlshow.test | 4 + mysql-test/t/temp_table.test | 25 ++-- mysys/mf_format.c | 16 +-- sql/ha_federated.cc | 1 - sql/item.cc | 46 +++---- sql/item.h | 15 +-- sql/item_func.cc | 25 ++-- sql/log_event.cc | 5 +- sql/opt_range.cc | 10 +- sql/sp_head.cc | 1 + sql/sql_class.cc | 14 +- sql/sql_parse.cc | 18 +-- sql/sql_prepare.cc | 100 +++++++------- sql/structs.h | 2 +- sql/table.cc | 3 +- sql/table.h | 2 - strings/decimal.c | 2 +- strings/longlong2str-x86.s | 137 ++++++++++---------- strings/my_strtoll10.c | 4 +- 40 files changed, 384 insertions(+), 366 deletions(-) diff --git a/BUILD/FINISH.sh b/BUILD/FINISH.sh index 8cd78bf4165..2fc8015ea28 100644 --- a/BUILD/FINISH.sh +++ b/BUILD/FINISH.sh @@ -14,7 +14,7 @@ path=`dirname $0` if [ -z "$just_clean" ] then commands="$commands -CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\" CXXLDFLAGS=\"$CXXLDFLAGS\" \ +CC=\"$CC\" CFLAGS=\"$cflags\" CXX=\"$CXX\" CXXFLAGS=\"$cxxflags\" CXXLDFLAGS=\"$CXXLDFLAGS\" \ $configure" fi diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 1603cfadbed..b9d96cf10b1 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -98,6 +98,10 @@ else make=make fi +if test -z "$CC" ; then + CC=gcc +fi + if test -z "$CXX" ; then CXX=gcc fi diff --git a/client/mysql.cc b/client/mysql.cc index f4361f77f4c..8a3e669c51d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -320,7 +320,7 @@ static void initialize_readline (char *name); static void fix_history(String *final_command); #endif -static COMMANDS *find_command (char *name,char cmd_name); +static COMMANDS *find_command(char *name,char cmd_name); static bool add_line(String &buffer,char *line,char *in_string, bool *ml_comment); static void remove_cntrl(String &buffer); @@ -1085,10 +1085,12 @@ static int read_and_execute(bool interactive) } -static COMMANDS *find_command (char *name,char cmd_char) +static COMMANDS *find_command(char *name,char cmd_char) { uint len; char *end; + DBUG_ENTER("find_command"); + DBUG_PRINT("enter",("name: '%s' char: %d", name ? name : "NULL", cmd_char)); if (!name) { @@ -1100,12 +1102,16 @@ static COMMANDS *find_command (char *name,char cmd_char) while (my_isspace(charset_info,*name)) name++; /* - As special case we allow row that starts with word delimiter - to be able to change delimiter if someone has delimiter 'delimiter'. + If there is an \\g in the row or if the row has a delimiter but + this is not a delimiter command, let add_line() take care of + parsing the row and calling find_command() */ if (strstr(name, "\\g") || (strstr(name, delimiter) && - strncmp(name, "delimiter", 9))) - return ((COMMANDS *) 0); + strlen(name) >= 9 && + my_strnncoll(charset_info,(uchar*) name, + 9, + (const uchar*) "delimiter", 9))) + DBUG_RETURN((COMMANDS *) 0); if ((end=strcont(name," \t"))) { len=(uint) (end - name); @@ -1121,15 +1127,18 @@ static COMMANDS *find_command (char *name,char cmd_char) for (uint i= 0; commands[i].name; i++) { if (commands[i].func && - ((name && + ((name && !my_strnncoll(charset_info,(uchar*)name,len, (uchar*)commands[i].name,len) && !commands[i].name[len] && (!end || (end && commands[i].takes_params))) || !name && commands[i].cmd_char == cmd_char)) - return (&commands[i]); + { + DBUG_PRINT("exit",("found command: %s", commands[i].name)); + DBUG_RETURN(&commands[i]); + } } - return ((COMMANDS *) 0); + DBUG_RETURN((COMMANDS *) 0); } @@ -1140,15 +1149,16 @@ static bool add_line(String &buffer,char *line,char *in_string, char buff[80], *pos, *out; COMMANDS *com; bool need_space= 0; + DBUG_ENTER("add_line"); if (!line[0] && buffer.is_empty()) - return 0; + DBUG_RETURN(0); #ifdef HAVE_READLINE if (status.add_to_history && line[0] && not_in_history(line)) add_history(line); #endif #ifdef USE_MB - char *strend=line+(uint) strlen(line); + char *end_of_line=line+(uint) strlen(line); #endif for (pos=out=line ; (inchar= (uchar) *pos) ; pos++) @@ -1157,13 +1167,14 @@ static bool add_line(String &buffer,char *line,char *in_string, buffer.is_empty()) continue; #ifdef USE_MB - int l; + int length; if (use_mb(charset_info) && - (l = my_ismbchar(charset_info, pos, strend))) { - while (l--) - *out++ = *pos++; - pos--; - continue; + (length= my_ismbchar(charset_info, pos, end_of_line))) + { + while (length--) + *out++ = *pos++; + pos--; + continue; } #endif if (!*ml_comment && inchar == '\\') @@ -1183,7 +1194,7 @@ static bool add_line(String &buffer,char *line,char *in_string, const String tmp(line,(uint) (out-line), charset_info); buffer.append(tmp); if ((*com->func)(&buffer,pos-1) > 0) - return 1; // Quit + DBUG_RETURN(1); // Quit if (com->takes_params) { for (pos++ ; @@ -1201,29 +1212,40 @@ static bool add_line(String &buffer,char *line,char *in_string, { sprintf(buff,"Unknown command '\\%c'.",inchar); if (put_info(buff,INFO_ERROR) > 0) - return 1; + DBUG_RETURN(1); *out++='\\'; *out++=(char) inchar; continue; } } - - else if (!*ml_comment && (*pos == *delimiter && - is_prefix(pos + 1, delimiter + 1)) && - !*in_string) + else if (!*ml_comment && !*in_string && + (*pos == *delimiter && is_prefix(pos + 1, delimiter + 1) || + buffer.length() == 0 && (out - line) >= 9 && + !my_strcasecmp(charset_info, line, "delimiter"))) { uint old_delimiter_length= delimiter_length; if (out != line) buffer.append(line, (uint) (out - line)); // Add this line if ((com= find_command(buffer.c_ptr(), 0))) { + if (com->func == com_delimiter) + { + /* + Delimiter wants the get rest of the given line as argument to + allow one to change ';' to ';;' and back + */ + char *end= strend(pos); + buffer.append(pos, (uint) (end - pos)); + /* Ensure pos will point at \0 after the pos+= below */ + pos= end - old_delimiter_length + 1; + } if ((*com->func)(&buffer, buffer.c_ptr()) > 0) - return 1; // Quit + DBUG_RETURN(1); // Quit } else { if (com_go(&buffer, 0) > 0) // < 0 is not fatal - return 1; + DBUG_RETURN(1); } buffer.length(0); out= line; @@ -1275,9 +1297,9 @@ static bool add_line(String &buffer,char *line,char *in_string, if (buffer.length() + length >= buffer.alloced_length()) buffer.realloc(buffer.length()+length+IO_SIZE); if (!(*ml_comment) && buffer.append(line,length)) - return 1; + DBUG_RETURN(1); } - return 0; + DBUG_RETURN(0); } /***************************************************************** diff --git a/client/mysqldump.c b/client/mysqldump.c index 322acbd26c0..9cf21230929 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1188,23 +1188,25 @@ static void print_xml_row(FILE *xml_file, const char *row_name, This function has logic to print the appropriate syntax depending on whether this is a procedure or functions - RETURN 0 succes, 1 if error + RETURN + 0 Success + 1 Error */ -static uint dump_routines_for_db (char *db) +static uint dump_routines_for_db(char *db) { char query_buff[512]; - const char *routine_type[]={"FUNCTION", "PROCEDURE"}; - char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3], *routine_name; + const char *routine_type[]= {"FUNCTION", "PROCEDURE"}; + char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3]; + char *routine_name; int i; - FILE *sql_file = md_result_file; + FILE *sql_file= md_result_file; MYSQL_RES *routine_res, *routine_list_res; MYSQL_ROW row, routine_list_row; - DBUG_ENTER("dump_routines_for_db"); + DBUG_PRINT("enter", ("db: '%s'", db)); mysql_real_escape_string(sock, db_name_buff, db, strlen(db)); - DBUG_PRINT("enter", ("db: '%s'", db_name_buff)); /* nice comments */ if (opt_comments) @@ -1217,10 +1219,10 @@ static uint dump_routines_for_db (char *db) if (lock_tables) mysql_query(sock, "LOCK TABLES mysql.proc READ"); - fprintf(sql_file, "DELIMITER //\n"); + fprintf(sql_file, "DELIMITER ;;\n"); /* 0, retrieve and dump functions, 1, procedures */ - for (i=0; i <= 1; i++) + for (i= 0; i <= 1; i++) { my_snprintf(query_buff, sizeof(query_buff), "SHOW %s STATUS WHERE Db = '%s'", @@ -1232,18 +1234,18 @@ static uint dump_routines_for_db (char *db) if (mysql_num_rows(routine_list_res)) { - while((routine_list_row= mysql_fetch_row(routine_list_res))) + while ((routine_list_row= mysql_fetch_row(routine_list_res))) { DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type[i], name_buff)); - routine_name=quote_name(routine_list_row[1], name_buff, 0); + routine_name= quote_name(routine_list_row[1], name_buff, 0); my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s", routine_type[i], routine_name); if (mysql_query_with_error_report(sock, &routine_res, query_buff)) DBUG_RETURN(1); - while ((row=mysql_fetch_row(routine_res))) + while ((row= mysql_fetch_row(routine_res))) { /* if the user has EXECUTE privilege he see routine names, but NOT the @@ -1254,16 +1256,18 @@ static uint dump_routines_for_db (char *db) if (strlen(row[2])) { if (opt_drop) - fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */ //\n", + fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;;\n", routine_type[i], routine_name); /* - we need to change sql_mode only for the CREATE PROCEDURE/FUNCTION - otherwise we may need to re-quote routine_name + we need to change sql_mode only for the CREATE + PROCEDURE/FUNCTION otherwise we may need to re-quote routine_name */; - fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/ //\n", + fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/;;\n", row[1] /* sql_mode */); - fprintf(sql_file, "/*!50003 %s */ //\n", row[2]); - fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ //\n"); + fprintf(sql_file, "/*!50003 %s */;;\n", row[2]); + fprintf(sql_file, + "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/" + ";;\n"); } } /* end of routine printing */ } /* end of list of routines */ @@ -1741,7 +1745,6 @@ static void dump_triggers_for_table (char *table, char *db) char name_buff[NAME_LEN*4+3], table_buff[NAME_LEN*2+3]; char query_buff[512]; FILE *sql_file = md_result_file; - DBUG_ENTER("dump_triggers_for_table"); DBUG_PRINT("enter", ("db: %s, table: %s", db, table)); result_table= quote_name(table, table_buff, 1); @@ -1759,11 +1762,11 @@ static void dump_triggers_for_table (char *table, char *db) } if (mysql_num_rows(result)) fprintf(sql_file, "\n/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n\ -DELIMITER //;\n"); +DELIMITER ;;\n"); while ((row=mysql_fetch_row(result))) { - fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\" */ //\n\ -/*!50003 CREATE TRIGGER %s %s %s ON %s FOR EACH ROW%s */ //\n\n", + fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n\ +/*!50003 CREATE TRIGGER %s %s %s ON %s FOR EACH ROW%s */;;\n\n", row[6], /* sql_mode */ quote_name(row[0], name_buff, 0), /* Trigger */ row[4], /* Timing */ @@ -1773,8 +1776,8 @@ DELIMITER //;\n"); } if (mysql_num_rows(result)) fprintf(sql_file, - "DELIMITER ;//\n\ -/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;"); + "DELIMITER ;\n" + "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;\n"); mysql_free_result(result); DBUG_VOID_RETURN; } @@ -1800,10 +1803,10 @@ static char *add_load_option(char *ptr,const char *object, /* -** Allow the user to specify field terminator strings like: -** "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline) -** This is done by doubleing ' and add a end -\ if needed to avoid -** syntax errors from the SQL parser. + Allow the user to specify field terminator strings like: + "'", "\", "\\" (escaped backslash), "\t" (tab), "\n" (newline) + This is done by doubling ' and add a end -\ if needed to avoid + syntax errors from the SQL parser. */ static char *field_escape(char *to,const char *from,uint length) diff --git a/client/mysqltest.c b/client/mysqltest.c index 0cad29bd8de..ce7b16fb121 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -135,7 +135,8 @@ typedef struct long code; } st_error; -static st_error global_error[] = { +static st_error global_error[] = +{ #include { 0, 0 } }; @@ -210,7 +211,8 @@ static int ps_match_re(char *); static char *ps_eprint(int); static void ps_free_reg(void); -static const char *embedded_server_groups[] = { +static const char *embedded_server_groups[]= +{ "server", "embedded", "mysqltest_SERVER", @@ -1273,7 +1275,7 @@ int do_modify_var(struct st_query *query, const char *name, if (*p != '$') die("First argument to %s must be a variable (start with $)", name); v= var_get(p, &p, 1, 0); - switch (operator){ + switch (operator) { case DO_DEC: v->int_val--; break; diff --git a/include/my_sys.h b/include/my_sys.h index c46da655fa4..11e8a36f5fa 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -98,7 +98,6 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_RETURN_REAL_PATH 32 /* return full path for file */ #define MY_SAFE_PATH 64 /* Return NULL if too long path */ #define MY_RELATIVE_PATH 128 /* name is relative to 'dir' */ -#define MY_UNIX_PATH 256 /* convert path to UNIX format */ /* My seek flags */ #define MY_SEEK_SET 0 diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 6a710a8de10..2cc56975056 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -541,16 +541,16 @@ create table t1 ( a timestamp ); alter table t1 add unique ( a(1) ); ERROR HY000: Incorrect sub part key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique sub keys drop table t1; -create database mysqltest1; +create database mysqltest; create table t1 (c1 int); -alter table t1 rename mysqltest1.t1; +alter table t1 rename mysqltest.t1; drop table t1; ERROR 42S02: Unknown table 't1' -alter table mysqltest1.t1 rename t1; +alter table mysqltest.t1 rename t1; drop table t1; create table t1 (c1 int); -use mysqltest1; -drop database mysqltest1; +use mysqltest; +drop database mysqltest; alter table test.t1 rename t1; ERROR 3D000: No database selected alter table test.t1 rename test.t1; diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 577f943ebde..b027cb33185 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -818,6 +818,9 @@ lpad(12345, 5, "#") SELECT conv(71, 10, 36), conv('1Z', 36, 10); conv(71, 10, 36) conv('1Z', 36, 10) 1Z 71 +SELECT conv(71, 10, 37), conv('1Z', 37, 10), conv(0,1,10),conv(0,0,10), conv(0,-1,10); +conv(71, 10, 37) conv('1Z', 37, 10) conv(0,1,10) conv(0,0,10) conv(0,-1,10) +NULL NULL NULL NULL NULL create table t1 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8; insert into t1 values (1,'aaaaaaaaaa'), (2,'bbbbbbbbbb'); create table t2 (id int(1), str varchar(10)) DEFAULT CHARSET=utf8; diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index e2812283901..d7ce6a7a96a 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -1,4 +1,5 @@ -DROP TABLE IF EXISTS t0,t1,t2,t3,t5; +DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5; +DROP VIEW IF EXISTS v1; show variables where variable_name like "skip_show_database"; Variable_name Value skip_show_database OFF @@ -638,8 +639,8 @@ use test; create function sub1(i int) returns int return i+1; create table t1(f1 int); -create view t2 (c) as select f1 from t1; -create view t3 (c) as select sub1(1); +create view v2 (c) as select f1 from t1; +create view v3 (c) as select sub1(1); create table t4(f1 int, KEY f1_key (f1)); drop table t1; drop function sub1; @@ -647,29 +648,29 @@ select table_name from information_schema.views where table_schema='test'; table_name Warnings: -Warning 1356 View 'test.t2' references invalid table(s) or column(s) or function(s) -Warning 1356 View 'test.t3' references invalid table(s) or column(s) or function(s) +Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) +Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) select table_name from information_schema.views where table_schema='test'; table_name Warnings: -Warning 1356 View 'test.t2' references invalid table(s) or column(s) or function(s) -Warning 1356 View 'test.t3' references invalid table(s) or column(s) or function(s) +Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) +Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) select column_name from information_schema.columns where table_schema='test'; column_name f1 Warnings: -Warning 1356 View 'test.t2' references invalid table(s) or column(s) or function(s) -Warning 1356 View 'test.t3' references invalid table(s) or column(s) or function(s) +Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) +Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) select index_name from information_schema.statistics where table_schema='test'; index_name f1_key select constraint_name from information_schema.table_constraints where table_schema='test'; constraint_name -drop view t2; -drop view t3; +drop view v2; +drop view v3; drop table t4; select * from information_schema.table_names; ERROR 42S02: Unknown table 'table_names' in information_schema diff --git a/mysql-test/r/information_schema_inno.result b/mysql-test/r/information_schema_inno.result index 9dd92baf62f..fb6584673f6 100644 --- a/mysql-test/r/information_schema_inno.result +++ b/mysql-test/r/information_schema_inno.result @@ -1,4 +1,4 @@ -DROP TABLE IF EXISTS t1,t2; +DROP TABLE IF EXISTS t1,t2,t3; CREATE TABLE t1 (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; CREATE TABLE t2 (id INT PRIMARY KEY, t1_id INT, INDEX par_ind (t1_id, id), FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE, diff --git a/mysql-test/r/multi_statement.result b/mysql-test/r/multi_statement.result index 3a8d86bf349..ff19cbdd698 100644 --- a/mysql-test/r/multi_statement.result +++ b/mysql-test/r/multi_statement.result @@ -1,3 +1,4 @@ +DROP TABLE IF EXISTS t1; select 1; 1 1 diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index eeb6abd9f41..76faa12373a 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -1,6 +1,7 @@ drop table if exists t1; create table t1(a int); insert into t1 values(1); +ERROR at line 9: DELIMITER must be followed by a 'delimiter' character or string Test default delimiter ; a diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 48e6ded689e..de59ec74135 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1828,31 +1828,32 @@ UNLOCK TABLES; /*!40000 ALTER TABLE `t1` ENABLE KEYS */; /*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/; -DELIMITER //; -/*!50003 SET SESSION SQL_MODE="" */ // +DELIMITER ;; +/*!50003 SET SESSION SQL_MODE="" */;; /*!50003 CREATE TRIGGER `trg1` BEFORE INSERT ON `t1` FOR EACH ROW begin if new.a > 10 then set new.a := 10; set new.a := 11; end if; -end */ // +end */;; -/*!50003 SET SESSION SQL_MODE="" */ // +/*!50003 SET SESSION SQL_MODE="" */;; /*!50003 CREATE TRIGGER `trg2` BEFORE UPDATE ON `t1` FOR EACH ROW begin if old.a % 2 = 0 then set new.b := 12; end if; -end */ // +end */;; -/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */ // +/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */;; /*!50003 CREATE TRIGGER `trg3` AFTER UPDATE ON `t1` FOR EACH ROW begin if new.a = -1 then set @fired:= "Yes"; end if; -end */ // +end */;; -DELIMITER ;// -/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;DROP TABLE IF EXISTS `t2`; +DELIMITER ; +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */; +DROP TABLE IF EXISTS `t2`; CREATE TABLE `t2` ( `a` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1; @@ -1864,17 +1865,18 @@ UNLOCK TABLES; /*!40000 ALTER TABLE `t2` ENABLE KEYS */; /*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/; -DELIMITER //; -/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */ // +DELIMITER ;; +/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */;; /*!50003 CREATE TRIGGER `trg4` BEFORE INSERT ON `t2` FOR EACH ROW begin if new.a > 10 then set @fired:= "No"; end if; -end */ // +end */;; -DELIMITER ;// +DELIMITER ; /*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */; + /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; @@ -2036,37 +2038,37 @@ LOCK TABLES `t1` WRITE; INSERT INTO `t1` VALUES (1),(2),(3),(4),(5); UNLOCK TABLES; /*!40000 ALTER TABLE `t1` ENABLE KEYS */; -DELIMITER // -/*!50003 DROP FUNCTION IF EXISTS `bug9056_func1` */ // -/*!50003 SET SESSION SQL_MODE=""*/ // +DELIMITER ;; +/*!50003 DROP FUNCTION IF EXISTS `bug9056_func1` */;; +/*!50003 SET SESSION SQL_MODE=""*/;; /*!50003 CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) -RETURN a+b */ // -/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // -/*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */ // -/*!50003 SET SESSION SQL_MODE=""*/ // +RETURN a+b */;; +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;; +/*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */;; +/*!50003 SET SESSION SQL_MODE=""*/;; /*!50003 CREATE FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) begin set f1= concat( 'hello', f1 ); return f1; -end */ // -/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // -/*!50003 DROP PROCEDURE IF EXISTS `a'b` */ // -/*!50003 SET SESSION SQL_MODE="REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI"*/ // +end */;; +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;; +/*!50003 DROP PROCEDURE IF EXISTS `a'b` */;; +/*!50003 SET SESSION SQL_MODE="REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI"*/;; /*!50003 CREATE PROCEDURE "a'b"() -select 1 */ // -/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // -/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc1` */ // -/*!50003 SET SESSION SQL_MODE=""*/ // +select 1 */;; +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;; +/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc1` */;; +/*!50003 SET SESSION SQL_MODE=""*/;; /*!50003 CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT) -BEGIN SELECT a+b INTO c; end */ // -/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // -/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc2` */ // -/*!50003 SET SESSION SQL_MODE=""*/ // +BEGIN SELECT a+b INTO c; end */;; +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;; +/*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc2` */;; +/*!50003 SET SESSION SQL_MODE=""*/;; /*!50003 CREATE PROCEDURE `bug9056_proc2`(OUT a INT) BEGIN select sum(id) from t1 into a; -END */ // -/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ // +END */;; +/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;; DELIMITER ; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; diff --git a/mysql-test/r/mysqlshow.result b/mysql-test/r/mysqlshow.result index a04a7081b34..355c20fdad3 100644 --- a/mysql-test/r/mysqlshow.result +++ b/mysql-test/r/mysqlshow.result @@ -1,3 +1,4 @@ +DROP TABLE IF EXISTS t1,t2; CREATE TABLE t1 (a int); INSERT INTO t1 VALUES (1),(2),(3); CREATE TABLE t2 (a int, b int); diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result index 726861bb525..82479504b10 100644 --- a/mysql-test/r/temp_table.result +++ b/mysql-test/r/temp_table.result @@ -1,4 +1,5 @@ drop table if exists t1,t2; +drop view if exists v1; CREATE TABLE t1 (c int not null, d char (10) not null); insert into t1 values(1,""),(2,"a"),(3,"b"); CREATE TEMPORARY TABLE t1 (a int not null, b char (10) not null); @@ -99,32 +100,32 @@ Variable_name Value Created_tmp_disk_tables 0 Created_tmp_tables 2 drop table t1; -create temporary table t1 as select 'This is temp. table' A; -create view t1 as select 'This is view' A; -select * from t1; +create temporary table v1 as select 'This is temp. table' A; +create view v1 as select 'This is view' A; +select * from v1; A This is temp. table -show create table t1; +show create table v1; Table Create Table -t1 CREATE TEMPORARY TABLE `t1` ( +v1 CREATE TEMPORARY TABLE `v1` ( `A` varchar(19) NOT NULL default '' ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -show create view t1; +show create view v1; View Create View -t1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `t1` AS select _latin1'This is view' AS `A` -drop view t1; -select * from t1; +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'This is view' AS `A` +drop view v1; +select * from v1; A This is temp. table -create view t1 as select 'This is view again' A; -select * from t1; +create view v1 as select 'This is view again' A; +select * from v1; A This is temp. table -drop table t1; -select * from t1; +drop table v1; +select * from v1; A This is view again -drop view t1; +drop view v1; create table t1 (a int, b int, index(a), index(b)); create table t2 (c int auto_increment, d varchar(255), primary key (c)); insert into t1 values (3,1),(3,2); diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 5695822be6b..2e5b68c1dc7 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -373,24 +373,24 @@ drop table t1; # Bug#11493 - Alter table rename to default database does not work without # db name qualifying # -create database mysqltest1; +create database mysqltest; create table t1 (c1 int); # Move table to other database. -alter table t1 rename mysqltest1.t1; +alter table t1 rename mysqltest.t1; # Assure that it has moved. --error 1051 drop table t1; # Move table back. -alter table mysqltest1.t1 rename t1; +alter table mysqltest.t1 rename t1; # Assure that it is back. drop table t1; # Now test for correct message if no database is selected. # Create t1 in 'test'. create table t1 (c1 int); # Change to other db. -use mysqltest1; +use mysqltest; # Drop the current db. This de-selects any db. -drop database mysqltest1; +drop database mysqltest; # Now test for correct message. --error 1046 alter table test.t1 rename t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 4a6c98c8d7f..8b14e674b2e 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -467,6 +467,7 @@ SELECT lpad(12345, 5, "#"); # SELECT conv(71, 10, 36), conv('1Z', 36, 10); +SELECT conv(71, 10, 37), conv('1Z', 37, 10), conv(0,1,10),conv(0,0,10), conv(0,-1,10); # # Bug in SUBSTRING when mixed with CONCAT and ORDER BY (Bug #3089) diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 51cca0a3db1..f351d315680 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -5,7 +5,8 @@ # show databases --disable_warnings -DROP TABLE IF EXISTS t0,t1,t2,t3,t5; +DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5; +DROP VIEW IF EXISTS v1; --enable_warnings @@ -364,8 +365,8 @@ use test; create function sub1(i int) returns int return i+1; create table t1(f1 int); -create view t2 (c) as select f1 from t1; -create view t3 (c) as select sub1(1); +create view v2 (c) as select f1 from t1; +create view v3 (c) as select sub1(1); create table t4(f1 int, KEY f1_key (f1)); drop table t1; drop function sub1; @@ -378,8 +379,8 @@ where table_schema='test'; select index_name from information_schema.statistics where table_schema='test'; select constraint_name from information_schema.table_constraints where table_schema='test'; -drop view t2; -drop view t3; +drop view v2; +drop view v3; drop table t4; # diff --git a/mysql-test/t/information_schema_inno.test b/mysql-test/t/information_schema_inno.test index dd7015bfd9a..9cd64a54ad9 100644 --- a/mysql-test/t/information_schema_inno.test +++ b/mysql-test/t/information_schema_inno.test @@ -1,6 +1,6 @@ -- source include/have_innodb.inc --disable_warnings -DROP TABLE IF EXISTS t1,t2; +DROP TABLE IF EXISTS t1,t2,t3; --enable_warnings # diff --git a/mysql-test/t/multi_statement.test b/mysql-test/t/multi_statement.test index eb8d867f3f0..785aa749f5e 100644 --- a/mysql-test/t/multi_statement.test +++ b/mysql-test/t/multi_statement.test @@ -1,6 +1,10 @@ # PS doesn't support multi-statements --disable_ps_protocol +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + select 1; delimiter ||||; select 2; diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index c1d9813ea39..31918cae619 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -14,7 +14,7 @@ create table t1(a int); insert into t1 values(1); # Test delimiters ---exec $MYSQL test < "./t/mysql_delimiter.sql" +--exec $MYSQL test 2>&1 < "./t/mysql_delimiter.sql" --disable_query_log # Test delimiter : supplied on the command line diff --git a/mysql-test/t/mysqlshow.test b/mysql-test/t/mysqlshow.test index 33ae8aef9a0..1e2e97a4e07 100644 --- a/mysql-test/t/mysqlshow.test +++ b/mysql-test/t/mysqlshow.test @@ -1,6 +1,10 @@ # Can't run test of external client with embedded server -- source include/not_embedded.inc +--disable_warnings +DROP TABLE IF EXISTS t1,t2; +--enable_warnings + # ## Bug #5036 mysqlshow is missing a column # diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test index 9a7678ed712..6b3991c9c78 100644 --- a/mysql-test/t/temp_table.test +++ b/mysql-test/t/temp_table.test @@ -4,6 +4,7 @@ --disable_warnings drop table if exists t1,t2; +drop view if exists v1; --enable_warnings CREATE TABLE t1 (c int not null, d char (10) not null); @@ -91,18 +92,18 @@ show status like "created_tmp%tables"; drop table t1; # Fix for BUG#8921: Check that temporary table is ingored by view commands. -create temporary table t1 as select 'This is temp. table' A; -create view t1 as select 'This is view' A; -select * from t1; -show create table t1; -show create view t1; -drop view t1; -select * from t1; -create view t1 as select 'This is view again' A; -select * from t1; -drop table t1; -select * from t1; -drop view t1; +create temporary table v1 as select 'This is temp. table' A; +create view v1 as select 'This is view' A; +select * from v1; +show create table v1; +show create view v1; +drop view v1; +select * from v1; +create view v1 as select 'This is view again' A; +select * from v1; +drop table v1; +select * from v1; +drop view v1; # Bug #8497: tmpdir with extra slashes would cause failures # diff --git a/mysys/mf_format.c b/mysys/mf_format.c index 0fec9d27b1d..50f354df1cd 100644 --- a/mysys/mf_format.c +++ b/mysys/mf_format.c @@ -17,13 +17,12 @@ #include "mysys_priv.h" #include - /* - Formats a filename with possible replace of directory of extension - Function can handle the case where 'to' == 'name' - For a description of the flag values, consult my_sys.h - The arguments should be in unix format. - */ - +/* + Formats a filename with possible replace of directory of extension + Function can handle the case where 'to' == 'name' + For a description of the flag values, consult my_sys.h + The arguments should be in unix format. +*/ my_string fn_format(my_string to, const char *name, const char *dir, const char *extension, uint flag) @@ -54,8 +53,7 @@ my_string fn_format(my_string to, const char *name, const char *dir, pack_dirname(dev,dev); /* Put in ./.. and ~/.. */ if (flag & MY_UNPACK_FILENAME) (void) unpack_dirname(dev,dev); /* Replace ~/.. with dir */ - if (flag & MY_UNIX_PATH) - to_unix_path(dev); /* Fix to MySQL representation */ + if ((pos= (char*) strchr(name,FN_EXTCHAR)) != NullS) { if ((flag & MY_REPLACE_EXT) == 0) /* If we should keep old ext */ diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 2590e7881a4..49a82ec0225 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -1315,7 +1315,6 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) query.append(FEDERATED_FROM); query.append(FEDERATED_BTICK); - if (!(share= (FEDERATED_SHARE *) my_multi_malloc(MYF(MY_WME), &share, sizeof(*share), diff --git a/sql/item.cc b/sql/item.cc index df57c301327..aa11793dd61 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -817,9 +817,12 @@ String *Item_splocal::val_str(String *sp) { DBUG_ASSERT(fixed); Item *it= this_item(); - String *ret= it->val_str(sp); + String *res= it->val_str(sp); null_value= it->null_value; + if (!res) + return NULL; + /* This way we mark returned value of val_str as const, so that various functions (e.g. CONCAT) won't try to @@ -836,12 +839,11 @@ String *Item_splocal::val_str(String *sp) Item_param class contain some more details on the topic. */ - if (!ret) - return NULL; - - str_value_ptr.set(ret->ptr(), ret->length(), - ret->charset()); - return &str_value_ptr; + if (res != &str_value) + str_value.set(res->ptr(), res->length(), res->charset()); + else + res->mark_as_const(); + return &str_value; } @@ -858,17 +860,13 @@ my_decimal *Item_splocal::val_decimal(my_decimal *decimal_value) bool Item_splocal::is_null() { Item *it= this_item(); - bool ret= it->is_null(); - null_value= it->null_value; - return ret; + return it->is_null(); } Item * Item_splocal::this_item() { - THD *thd= current_thd; - return thd->spcont->get_item(m_offset); } @@ -882,25 +880,23 @@ Item_splocal::this_item_addr(THD *thd, Item **addr) Item * Item_splocal::this_const_item() const { - THD *thd= current_thd; - return thd->spcont->get_item(m_offset); } Item::Type Item_splocal::type() const { - THD *thd= current_thd; - - if (thd->spcont) + if (thd && thd->spcont) return thd->spcont->get_item(m_offset)->type(); return NULL_ITEM; // Anything but SUBSELECT_ITEM } -bool Item_splocal::fix_fields(THD *, Item **) +bool Item_splocal::fix_fields(THD *thd_arg, Item **ref) { - Item *it= this_item(); + Item *it; + thd= thd_arg; // Must be set before this_item() + it= this_item(); DBUG_ASSERT(it->fixed); max_length= it->max_length; decimals= it->decimals; @@ -927,6 +923,7 @@ void Item_splocal::print(String *str) /***************************************************************************** Item_name_const methods *****************************************************************************/ + double Item_name_const::val_real() { DBUG_ASSERT(fixed); @@ -965,9 +962,7 @@ my_decimal *Item_name_const::val_decimal(my_decimal *decimal_value) bool Item_name_const::is_null() { - bool ret= value_item->is_null(); - null_value= value_item->null_value; - return ret; + return value_item->is_null(); } Item::Type Item_name_const::type() const @@ -976,7 +971,7 @@ Item::Type Item_name_const::type() const } -bool Item_name_const::fix_fields(THD *thd, Item **) +bool Item_name_const::fix_fields(THD *thd, Item **ref) { char buf[128]; String *item_name; @@ -2776,7 +2771,7 @@ int Item_copy_string::save_in_field(Field *field, bool no_conversions) */ /* ARGSUSED */ -bool Item::fix_fields(THD *thd, Item ** ref) +bool Item::fix_fields(THD *thd, Item **ref) { // We do not check fields which are fixed during construction @@ -4758,8 +4753,7 @@ String *Item_ref::val_str(String* tmp) bool Item_ref::is_null() { DBUG_ASSERT(fixed); - (void) (*ref)->val_int_result(); - return (*ref)->null_value; + return (*ref)->is_null(); } diff --git a/sql/item.h b/sql/item.h index 381ba98e193..6485e4e7555 100644 --- a/sql/item.h +++ b/sql/item.h @@ -718,13 +718,7 @@ class Item_splocal : public Item public: LEX_STRING m_name; - - /* - Buffer, pointing to the string value of the item. We need it to - protect internal buffer from changes. See comment to analogous - member in Item_param for more details. - */ - String str_value_ptr; + THD *thd; /* Position of this reference to SP variable in the statement (the @@ -736,10 +730,10 @@ public: Value of 0 means that this object doesn't corresponding to reference to SP variable in query text. */ - int pos_in_query; + uint pos_in_query; - Item_splocal(LEX_STRING name, uint offset, int pos_in_q=0) - : m_offset(offset), m_name(name), pos_in_query(pos_in_q) + Item_splocal(LEX_STRING name, uint offset, uint pos_in_q=0) + : m_offset(offset), m_name(name), thd(0), pos_in_query(pos_in_q) { maybe_null= TRUE; } @@ -1502,6 +1496,7 @@ public: my_decimal *val_decimal(my_decimal *); int save_in_field(Field *field, bool no_conversions); enum Item_result result_type () const { return STRING_RESULT; } + enum Item_result cast_to_int_type() const { return INT_RESULT; } enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; } // to prevent drop fixed flag (no need parent cleanup call) void cleanup() {} diff --git a/sql/item_func.cc b/sql/item_func.cc index 518fb011e0f..59036d8ecb3 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2015,7 +2015,6 @@ String *Item_func_min_max::val_str(String *str) { String *res; LINT_INIT(res); - null_value= 0; for (uint i=0; i < arg_count ; i++) { if (i == 0) @@ -2030,14 +2029,11 @@ String *Item_func_min_max::val_str(String *str) if ((cmp_sign < 0 ? cmp : -cmp) < 0) res=res2; } - else - res= 0; } if ((null_value= args[i]->null_value)) - break; + return 0; } - if (res) // If !NULL - res->set_charset(collation.collation); + res->set_charset(collation.collation); return res; } case ROW_RESULT: @@ -2054,7 +2050,6 @@ double Item_func_min_max::val_real() { DBUG_ASSERT(fixed == 1); double value=0.0; - null_value= 0; for (uint i=0; i < arg_count ; i++) { if (i == 0) @@ -2076,7 +2071,6 @@ longlong Item_func_min_max::val_int() { DBUG_ASSERT(fixed == 1); longlong value=0; - null_value= 0; for (uint i=0; i < arg_count ; i++) { if (i == 0) @@ -2097,21 +2091,21 @@ longlong Item_func_min_max::val_int() my_decimal *Item_func_min_max::val_decimal(my_decimal *dec) { DBUG_ASSERT(fixed == 1); - my_decimal tmp_buf, *tmp, *res= NULL; - null_value= 0; + my_decimal tmp_buf, *tmp, *res; + LINT_INIT(res); + for (uint i=0; i < arg_count ; i++) { if (i == 0) res= args[i]->val_decimal(dec); else { - tmp= args[i]->val_decimal(&tmp_buf); - if (args[i]->null_value) - res= 0; - else if ((my_decimal_cmp(tmp, res) * cmp_sign) < 0) + tmp= args[i]->val_decimal(&tmp_buf); // Zero if NULL + if (tmp && (my_decimal_cmp(tmp, res) * cmp_sign) < 0) { if (tmp == &tmp_buf) { + /* Move value out of tmp_buf as this will be reused on next loop */ my_decimal2decimal(tmp, dec); res= dec; } @@ -2120,7 +2114,10 @@ my_decimal *Item_func_min_max::val_decimal(my_decimal *dec) } } if ((null_value= args[i]->null_value)) + { + res= 0; break; + } } return res; } diff --git a/sql/log_event.cc b/sql/log_event.cc index 5cb4c289a10..55c761d4c6e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -121,8 +121,9 @@ static char *pretty_print_str(char *packet, char *str, int len) static inline char* slave_load_file_stem(char*buf, uint file_id, int event_server_id) { - fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", - MY_UNPACK_FILENAME | MY_UNIX_PATH); + fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME); + to_unix_path(buf); + buf = strend(buf); buf = int10_to_str(::server_id, buf, 10); *buf++ = '-'; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index cb250251155..4d2020fd335 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -7039,19 +7039,15 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree) */ if (thd->query_id == cur_field->query_id) { - bool is_covered= FALSE; KEY_PART_INFO *key_part= cur_index_info->key_part; KEY_PART_INFO *key_part_end= key_part + cur_index_info->key_parts; - for (; key_part != key_part_end ; key_part++) + for (;;) { if (key_part->field == cur_field) - { - is_covered= TRUE; break; - } + if (++key_part == key_part_end) + goto next_index; // Field was not part of key } - if (!is_covered) - goto next_index; } } } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 1a7599d7bbc..80151862bbb 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -779,6 +779,7 @@ static bool subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) splocal < sp_vars_uses.back(); splocal++) { Item *val; + (*splocal)->thd= thd; // fix_fields() is not yet done /* append the text between sp ref occurences */ res|= qbuf.append(cur + prev_pos, (*splocal)->pos_in_query - prev_pos); prev_pos= (*splocal)->pos_in_query + (*splocal)->m_name.length; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 2699a4fa628..7eb0dcd2baf 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1709,15 +1709,19 @@ Statement_map::Statement_map() : int Statement_map::insert(Statement *statement) { - int rc= my_hash_insert(&st_hash, (byte *) statement); + int res= my_hash_insert(&st_hash, (byte *) statement); + if (res) + return res; if (statement->name.str) { - if ((rc= my_hash_insert(&names_hash, (byte*)statement))) + if ((res= my_hash_insert(&names_hash, (byte*)statement))) + { hash_delete(&st_hash, (byte*)statement); + return res; + } } - if (rc == 0) - last_found_statement= statement; - return rc; + last_found_statement= statement; + return res; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e83530b7239..2ada88c47d3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4483,7 +4483,8 @@ end_with_restore_list: command[thd->lex->create_view_mode].length); view_store_options(thd, first_table, &buff); buff.append("VIEW ", 5); - if (!first_table->current_db_used) + /* Test if user supplied a db (ie: we did not use thd->db) */ + if (first_table->db != thd->db && first_table->db[0]) { append_identifier(thd, &buff, first_table->db, first_table->db_length); @@ -4808,7 +4809,6 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, bool db_is_pattern= test(want_access & GRANT_ACL); #endif ulong dummy; - const char *db_name; DBUG_ENTER("check_access"); DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu", db ? db : "", want_access, thd->master_access)); @@ -4826,11 +4826,11 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv, DBUG_RETURN(TRUE); /* purecov: tested */ } - db_name= db ? db : thd->db; if (schema_db) { if (want_access & ~(SELECT_ACL | EXTRA_ACL)) { + const char *db_name= db ? db : thd->db; if (!no_errors) my_error(ER_DBACCESS_DENIED_ERROR, MYF(0), thd->priv_user, thd->priv_host, db_name); @@ -6084,14 +6084,12 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, { ptr->db= thd->db; ptr->db_length= thd->db_length; - ptr->current_db_used= 1; } else { /* The following can't be "" as we may do 'casedn_str()' on it */ ptr->db= empty_c_string; ptr->db_length= 0; - ptr->current_db_used= 1; } if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute()) ptr->db= thd->strdup(ptr->db); @@ -7398,15 +7396,13 @@ bool default_view_definer(THD *thd, st_lex_user *definer) { definer->user.str= thd->priv_user; definer->user.length= strlen(thd->priv_user); - if (*thd->priv_host != 0) - { - definer->host.str= thd->priv_host; - definer->host.length= strlen(thd->priv_host); - } - else + if (!*thd->priv_host) { my_error(ER_NO_VIEW_USER, MYF(0)); return TRUE; } + + definer->host.str= thd->priv_host; + definer->host.length= strlen(thd->priv_host); return FALSE; } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 6eea101de8f..e9777951db4 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -88,6 +88,11 @@ When one supplies long data for a placeholder: class Prepared_statement: public Statement { public: + enum flag_values + { + IS_IN_USE= 1 + }; + THD *thd; Protocol *protocol; Item_param **param_array; @@ -116,19 +121,8 @@ public: bool execute(String *expanded_query, bool open_cursor); /* Destroy this statement */ bool deallocate(); - - /* Possible values of flags */ -#if defined(_MSC_VER) && _MSC_VER < 1300 - static const int IS_IN_USE; -#else - static const int IS_IN_USE= 1; -#endif }; -/* VC6 can't handle initializing in declaration */ -#if defined(_MSC_VER) && _MSC_VER < 1300 -const int Prepared_statement::IS_IN_USE= 1; -#endif /****************************************************************************** Implementation @@ -1830,7 +1824,7 @@ static void cleanup_stmt_and_thd_after_use(Statement *stmt, THD *thd) void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length) { Prepared_statement *stmt= new Prepared_statement(thd, &thd->protocol_prep); - bool rc; + bool error; DBUG_ENTER("mysql_stmt_prepare"); DBUG_PRINT("prep_query", ("%s", packet)); @@ -1853,12 +1847,12 @@ void mysql_stmt_prepare(THD *thd, const char *packet, uint packet_length) if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); - rc= stmt->prepare(packet, packet_length); + error= stmt->prepare(packet, packet_length); if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),WAIT_PRIOR); - if (rc) + if (error) { /* Statement map deletes statement on erase */ thd->stmt_map.erase(stmt); @@ -1900,7 +1894,7 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len) CHARSET_INFO *to_cs= thd->variables.collation_connection; bool needs_conversion; user_var_entry *entry; - String *pstr= &str; + String *var_value= &str; uint32 unused, len; /* Convert @var contents to string in connection character set. Although @@ -1914,13 +1908,13 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len) && entry->value) { my_bool is_var_null; - pstr= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC); + var_value= entry->val_str(&is_var_null, &str, NOT_FIXED_DEC); /* NULL value of variable checked early as entry->value so here we can't get NULL in normal conditions */ DBUG_ASSERT(!is_var_null); - if (!pstr) + if (!var_value) goto end; } else @@ -1932,22 +1926,25 @@ static const char *get_dynamic_sql_string(LEX *lex, uint *query_len) str.set("NULL", 4, &my_charset_latin1); } - needs_conversion= String::needs_conversion(pstr->length(), - pstr->charset(), to_cs, &unused); + needs_conversion= String::needs_conversion(var_value->length(), + var_value->charset(), to_cs, + &unused); - len= needs_conversion ? pstr->length() * to_cs->mbmaxlen : pstr->length(); + len= (needs_conversion ? var_value->length() * to_cs->mbmaxlen : + var_value->length()); if (!(query_str= alloc_root(thd->mem_root, len+1))) goto end; if (needs_conversion) { uint dummy_errors; - len= copy_and_convert(query_str, len, to_cs, pstr->ptr(), pstr->length(), - pstr->charset(), &dummy_errors); + len= copy_and_convert(query_str, len, to_cs, var_value->ptr(), + var_value->length(), var_value->charset(), + &dummy_errors); } else - memcpy(query_str, pstr->ptr(), pstr->length()); - query_str[len]= '\0'; + memcpy(query_str, var_value->ptr(), var_value->length()); + query_str[len]= '\0'; // Safety (mostly for debug) *query_len= len; } else @@ -1997,10 +1994,9 @@ void mysql_sql_stmt_prepare(THD *thd) Prepared_statement *stmt; const char *query; uint query_len; - DBUG_ENTER("mysql_sql_stmt_prepare"); - DBUG_ASSERT(thd->protocol == &thd->protocol_simple); + if ((stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name))) { /* @@ -2182,7 +2178,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) uchar *packet_end= (uchar *) packet + packet_length - 1; #endif Prepared_statement *stmt; - bool rc; + bool error; DBUG_ENTER("mysql_stmt_execute"); packet+= 9; /* stmt_id + 5 bytes of flags */ @@ -2217,11 +2213,11 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) #endif if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); - rc= stmt->execute(&expanded_query, + error= stmt->execute(&expanded_query, test(flags & (ulong) CURSOR_TYPE_READ_ONLY)); if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), WAIT_PRIOR); - if (rc) + if (error) goto err; mysql_log.write(thd, COM_STMT_EXECUTE, "[%lu] %s", stmt->id, thd->query); @@ -2263,9 +2259,7 @@ void mysql_sql_stmt_execute(THD *thd) LEX_STRING *name= &lex->prepared_stmt_name; /* Query text for binary, general or slow log, if any of them is open */ String expanded_query; - DBUG_ENTER("mysql_sql_stmt_execute"); - DBUG_PRINT("info", ("EXECUTE: %.*s\n", name->length, name->str)); if (!(stmt= (Prepared_statement*) thd->stmt_map.find_by_name(name))) @@ -2412,7 +2406,6 @@ void mysql_stmt_close(THD *thd, char *packet) /* There is always space for 4 bytes in packet buffer */ ulong stmt_id= uint4korr(packet); Prepared_statement *stmt; - DBUG_ENTER("mysql_stmt_close"); if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close"))) @@ -2422,7 +2415,7 @@ void mysql_stmt_close(THD *thd, char *packet) The only way currently a statement can be deallocated when it's in use is from within Dynamic SQL. */ - DBUG_ASSERT(! (stmt->flags & Prepared_statement::IS_IN_USE)); + DBUG_ASSERT(! (stmt->flags & (uint) Prepared_statement::IS_IN_USE)); (void) stmt->deallocate(); DBUG_VOID_RETURN; @@ -2466,7 +2459,7 @@ void mysql_sql_stmt_close(THD *thd) mysql_stmt_get_longdata() thd Thread handle packet String to append - packet_length Length of string + packet_length Length of string (including end \0) DESCRIPTION Get a part of a long data. To make the protocol efficient, we are @@ -2483,13 +2476,12 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) Prepared_statement *stmt; Item_param *param; char *packet_end= packet + packet_length - 1; - DBUG_ENTER("mysql_stmt_get_longdata"); statistic_increment(thd->status_var.com_stmt_send_long_data, &LOCK_status); #ifndef EMBEDDED_LIBRARY /* Minimal size of long data packet is 6 bytes */ - if ((ulong) (packet_end - packet) < MYSQL_LONG_DATA_HEADER) + if (packet_length <= MYSQL_LONG_DATA_HEADER) { my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_send_long_data"); DBUG_VOID_RETURN; @@ -2542,7 +2534,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg) param_array(0), param_count(0), last_errno(0), - flags(IS_IN_USE) + flags((uint) IS_IN_USE) { *last_error= '\0'; } @@ -2676,7 +2668,7 @@ bool Prepared_statement::set_name(LEX_STRING *name_arg) bool Prepared_statement::prepare(const char *packet, uint packet_len) { - bool rc; + bool error; Statement stmt_backup; Query_arena *old_stmt_arena; DBUG_ENTER("Prepared_statement::prepare"); @@ -2707,7 +2699,7 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) lex->safe_to_cache_query= FALSE; lex->stmt_prepare_mode= TRUE; - rc= yyparse((void *)thd) || thd->is_fatal_error || + error= yyparse((void *)thd) || thd->is_fatal_error || thd->net.report_error || init_param_array(this); /* While doing context analysis of the query (in check_prepared_statement) @@ -2731,10 +2723,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) */ DBUG_ASSERT(thd->free_list == NULL); - if (rc == 0) - rc= check_prepared_statement(this, name.str != 0); + if (error == 0) + error= check_prepared_statement(this, name.str != 0); - if (rc && thd->lex->sphead) + if (error && thd->lex->sphead) { delete thd->lex->sphead; thd->lex->sphead= NULL; @@ -2745,14 +2737,14 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) thd->restore_backup_statement(this, &stmt_backup); thd->stmt_arena= old_stmt_arena; - if (rc == 0) + if (error == 0) { setup_set_params(); init_stmt_after_parse(lex); state= Query_arena::PREPARED; - flags&= ~IS_IN_USE; + flags&= ~ (uint) IS_IN_USE; } - DBUG_RETURN(rc); + DBUG_RETURN(error); } /* @@ -2774,6 +2766,10 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) Preconditions, postconditions. ------------------------------ See the comment for Prepared_statement::prepare(). + + RETURN + FALSE ok + TRUE Error */ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) @@ -2781,7 +2777,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) Statement stmt_backup; Query_arena *old_stmt_arena; Item *old_free_list; - bool rc= 1; + bool error= TRUE; statistic_increment(thd->status_var.com_stmt_execute, &LOCK_status); @@ -2791,13 +2787,11 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) my_message(last_errno, last_error, MYF(0)); return 1; } - if (flags & IS_IN_USE) + if (flags & (uint) IS_IN_USE) { my_error(ER_PS_NO_RECURSION, MYF(0)); return 1; } - /* In case the command has a call to SP which re-uses this statement name */ - flags|= IS_IN_USE; if (cursor && cursor->is_open()) close_cursor(); @@ -2891,11 +2885,11 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) if (state == Query_arena::PREPARED) state= Query_arena::EXECUTED; - rc= 0; + error= FALSE; error: thd->lock_id= &thd->main_lock_id; - flags&= ~IS_IN_USE; - return rc; + flags&= ~ (uint) IS_IN_USE; + return error; } @@ -2905,7 +2899,7 @@ bool Prepared_statement::deallocate() { /* We account deallocate in the same manner as mysql_stmt_close */ statistic_increment(thd->status_var.com_stmt_close, &LOCK_status); - if (flags & IS_IN_USE) + if (flags & (uint) IS_IN_USE) { my_error(ER_PS_NO_RECURSION, MYF(0)); return TRUE; diff --git a/sql/structs.h b/sql/structs.h index 03176b47360..199eceda30f 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -20,7 +20,7 @@ struct st_table; class Field; -#define STRING_WITH_LEN(X) X, (sizeof(X)-1) +#define STRING_WITH_LEN(X) ((char*) X), (sizeof(X)-1) typedef struct st_lex_string { diff --git a/sql/table.cc b/sql/table.cc index 74ffe58e42e..6319afcd01b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -287,7 +287,8 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat, keynames=(char*) key_part; strpos+= (strmov(keynames, (char *) strpos) - keynames)+1; - share->null_bytes= null_pos - (uchar*) outparam->null_flags + (null_bit_pos + 7) / 8; + share->null_bytes= ((uint) (null_pos - (uchar*) outparam->null_flags) + + (null_bit_pos + 7) / 8); share->reclength = uint2korr((head+16)); if (*(head+26) == 1) diff --git a/sql/table.h b/sql/table.h index 43b6fddeee6..4a28e6d17a5 100644 --- a/sql/table.h +++ b/sql/table.h @@ -582,8 +582,6 @@ typedef struct st_table_list bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */ /* view where processed */ bool where_processed; - /* db part was not defined in table definition */ - bool current_db_used; /* FRMTYPE_ERROR if any type is acceptable */ enum frm_type_enum required_type; char timestamp_buffer[20]; /* buffer for timestamp (19+1) */ diff --git a/strings/decimal.c b/strings/decimal.c index 7816f340eef..b7ad81ab53c 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -2018,7 +2018,7 @@ int decimal_mul(decimal_t *from1, decimal_t *from2, decimal_t *to) if (to->buf < buf1) { dec1 *cur_d= to->buf; - for (; d_to_move; d_to_move--, cur_d++, buf1++) + for (; d_to_move--; cur_d++, buf1++) *cur_d= *buf1; } return error; diff --git a/strings/longlong2str-x86.s b/strings/longlong2str-x86.s index 1840bab3f47..168dab38a85 100644 --- a/strings/longlong2str-x86.s +++ b/strings/longlong2str-x86.s @@ -26,95 +26,88 @@ .type longlong2str_with_dig_vector,@function longlong2str_with_dig_vector: - subl $80,%esp + subl $80,%esp # Temporary buffer for up to 64 radix-2 digits pushl %ebp pushl %esi pushl %edi pushl %ebx - movl 100(%esp),%esi # Lower part of val - movl 112(%esp),%ebx # Radix - movl 104(%esp),%ebp # Higher part of val - movl %ebx,%eax - movl 108(%esp),%edi # get dst - testl %eax,%eax - jge .L144 + movl 100(%esp),%esi # esi = Lower part of val + movl 112(%esp),%ebx # ebx = Radix + movl 104(%esp),%ebp # ebp = Higher part of val + movl 108(%esp),%edi # edi = dst - addl $36,%eax - cmpl $34,%eax - ja .Lerror # Wrong radix - testl %ebp,%ebp - jge .L146 + testl %ebx,%ebx + jge .L144 # Radix was positive + negl %ebx # Change radix to positive + testl %ebp,%ebp # Test if given value is negative + jge .L144 movb $45,(%edi) # Add sign incl %edi # Change sign of val negl %esi adcl $0,%ebp negl %ebp -.L146: - negl %ebx # Change radix to positive - jmp .L148 - .align 4 -.L144: - addl $-2,%eax + +.L144: # Test that radix is between 2 and 36 + movl %ebx, %eax + addl $-2,%eax # Test that radix is between 2 and 36 cmpl $34,%eax - ja .Lerror # Radix in range + ja .Lerror # Radix was not in range -.L148: - movl %esi,%eax # Test if zero (for easy loop) - orl %ebp,%eax - jne .L150 - movb $48,(%edi) - incl %edi - jmp .L10_end - .align 4 - -.L150: leal 92(%esp),%ecx # End of buffer movl %edi, 108(%esp) # Store possible modified dest movl 116(%esp), %edi # dig_vec_upper - jmp .L155 - .align 4 + testl %ebp,%ebp # Test if value > 0xFFFFFFFF + jne .Llongdiv + cmpl %ebx, %esi # Test if <= radix, for easy loop + movl %esi, %eax # Value in eax (for Llow) + jae .Llow -.L153: - # val is stored in in ebp:esi + # Value is one digit (negative or positive) + movb (%eax,%edi),%bl + movl 108(%esp),%edi # get dst + movb %bl,(%edi) + incl %edi # End null here + jmp .L10_end - movl %ebp,%eax # High part of value +.Llongdiv: + # Value in ebp:esi. div the high part by the radix, + # then div remainder + low part by the radix. + movl %ebp,%eax # edx=0,eax=high(from ebp) xorl %edx,%edx + decl %ecx divl %ebx - movl %eax,%ebp + movl %eax,%ebp # edx=result of last, eax=low(from esi) movl %esi,%eax divl %ebx - decl %ecx - movl %eax,%esi # quotent in ebp:esi - movb (%edx,%edi),%al # al is faster than dl - movb %al,(%ecx) # store value in buff - .align 4 -.L155: + movl %eax,%esi # ebp:esi = quotient + movb (%edx,%edi),%dl # Store result number in temporary buffer testl %ebp,%ebp - ja .L153 - testl %esi,%esi # rest value - jl .L153 - je .L160 # Ready - movl %esi,%eax + movb %dl,(%ecx) # store value in buff + ja .Llongdiv # (Higher part of val still > 0) + .align 4 - -.L154: # Do rest with integer precision - cltd - divl %ebx +.Llow: # Do rest with integer precision + # Value in 0:eax. div 0 + low part by the radix. + xorl %edx,%edx decl %ecx + divl %ebx movb (%edx,%edi),%dl # bh is always zero as ebx=radix < 36 testl %eax,%eax movb %dl,(%ecx) - jne .L154 + jne .Llow .L160: movl 108(%esp),%edi # get dst - -.L10_mov: - movl %ecx,%esi - leal 92(%esp),%ecx # End of buffer - subl %esi,%ecx - rep - movsb + +.Lcopy_end: + leal 92(%esp),%esi # End of buffer +.Lmov: # mov temporary buffer to result (%ecx -> %edi) + movb (%ecx), %al + movb %al, (%edi) + incl %ecx + incl %edi + cmpl %ecx,%esi + jne .Lmov .L10_end: movl %edi,%eax # Pointer to end null @@ -166,21 +159,23 @@ longlong10_to_str: negl %esi # Change sign of val (ebp:esi) adcl $0,%ebp negl %ebp - .align 4 .L10_10: leal 92(%esp),%ecx # End of buffer - movl %esi,%eax # Test if zero (for easy loop) - orl %ebp,%eax - jne .L10_30 # Not zero + testl %ebp,%ebp # Test if value > 0xFFFFFFFF + jne .L10_longdiv + cmpl $10, %esi # Test if <= radix, for easy loop + movl %esi, %ebx # Value in eax (for L10_low) + jae .L10_low - # Here when value is zero - movb $48,(%edi) + # Value is one digit (negative or positive) + addb $48, %bl + movb %bl,(%edi) incl %edi jmp .L10_end .align 4 -.L10_20: +.L10_longdiv: # val is stored in in ebp:esi movl %ebp,%eax # High part of value xorl %edx,%edx @@ -195,17 +190,15 @@ longlong10_to_str: .L10_30: testl %ebp,%ebp - ja .L10_20 - testl %esi,%esi # rest value - jl .L10_20 # Unsigned, do ulonglong div once more - je .L10_mov # Ready + ja .L10_longdiv movl %esi,%ebx # Move val to %ebx +.L10_low: # The following code uses some tricks to change division by 10 to # multiplication and shifts movl $0xcccccccd,%esi -.L10_40: +.L10_40: # Divide %ebx with 10 movl %ebx,%eax mull %esi decl %ecx @@ -218,7 +211,7 @@ longlong10_to_str: movl %edx,%ebx testl %ebx,%ebx jne .L10_40 - jmp .L10_mov # Shared end with longlong10_to_str + jmp .Lcopy_end # Shared end with longlong2str .L10end: .size longlong10_to_str,.L10end-longlong10_to_str diff --git a/strings/my_strtoll10.c b/strings/my_strtoll10.c index 1f4cf1435fe..c1ad9bf1027 100644 --- a/strings/my_strtoll10.c +++ b/strings/my_strtoll10.c @@ -21,8 +21,8 @@ #undef ULONGLONG_MAX /* Needed under MetroWerks Compiler, since MetroWerks compiler does not properly handle a constant expression containing a mod operator */ #if defined(__NETWARE__) && defined(__MWERKS__) -ulonglong tmp; -#define ULONGLONG_MAX (tmp =(~(ulonglong) 0)) +static ulonglong ulonglong_max= ~(ulonglong) 0; +#define ULONGLONG_MAX ulonglong_max #else #define ULONGLONG_MAX (~(ulonglong) 0) #endif /* __NETWARE__ && __MWERKS__ */ From 4a893c96e37ca2b8cd4469d6d81f4f9309a242b1 Mon Sep 17 00:00:00 2001 From: "jimw@mysql.com" <> Date: Thu, 6 Oct 2005 17:37:24 -0700 Subject: [PATCH 03/13] Fix use of "%*s" *printf() specifiers that were really meant to be "%.*s". (Bug #13650) --- sql/sp.cc | 31 ++++++++++++++++--------------- sql/sp_cache.cc | 2 +- sql/sp_head.cc | 4 ++-- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index 4f7b544f5c7..8386c5d58a2 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -208,7 +208,7 @@ db_find_routine_aux(THD *thd, int type, sp_name *name, TABLE *table) { byte key[MAX_KEY_LENGTH]; // db, name, optional key length type DBUG_ENTER("db_find_routine_aux"); - DBUG_PRINT("enter", ("type: %d name: %*s", + DBUG_PRINT("enter", ("type: %d name: %.*s", type, name->m_name.length, name->m_name.str)); /* @@ -275,7 +275,7 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp) ulong sql_mode; Open_tables_state open_tables_state_backup; DBUG_ENTER("db_find_routine"); - DBUG_PRINT("enter", ("type: %d name: %*s", + DBUG_PRINT("enter", ("type: %d name: %.*s", type, name->m_name.length, name->m_name.str)); *sphp= 0; // In case of errors @@ -479,7 +479,8 @@ db_create_routine(THD *thd, int type, sp_head *sp) char olddb[128]; bool dbchanged; DBUG_ENTER("db_create_routine"); - DBUG_PRINT("enter", ("type: %d name: %*s",type,sp->m_name.length,sp->m_name.str)); + DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length, + sp->m_name.str)); dbchanged= FALSE; if ((ret= sp_use_new_db(thd, sp->m_db.str, olddb, sizeof(olddb), @@ -606,7 +607,7 @@ db_drop_routine(THD *thd, int type, sp_name *name) TABLE *table; int ret; DBUG_ENTER("db_drop_routine"); - DBUG_PRINT("enter", ("type: %d name: %*s", + DBUG_PRINT("enter", ("type: %d name: %.*s", type, name->m_name.length, name->m_name.str)); if (!(table= open_proc_table_for_update(thd))) @@ -628,7 +629,7 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) int ret; bool opened; DBUG_ENTER("db_update_routine"); - DBUG_PRINT("enter", ("type: %d name: %*s", + DBUG_PRINT("enter", ("type: %d name: %.*s", type, name->m_name.length, name->m_name.str)); if (!(table= open_proc_table_for_update(thd))) @@ -922,7 +923,7 @@ sp_find_procedure(THD *thd, sp_name *name, bool cache_only) { sp_head *sp; DBUG_ENTER("sp_find_procedure"); - DBUG_PRINT("enter", ("name: %*s.%*s", + DBUG_PRINT("enter", ("name: %.*s.%.*s", name->m_db.length, name->m_db.str, name->m_name.length, name->m_name.str)); @@ -980,7 +981,7 @@ sp_create_procedure(THD *thd, sp_head *sp) { int ret; DBUG_ENTER("sp_create_procedure"); - DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", sp->m_name.length, sp->m_name.str)); ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, sp); DBUG_RETURN(ret); @@ -992,7 +993,7 @@ sp_drop_procedure(THD *thd, sp_name *name) { int ret; DBUG_ENTER("sp_drop_procedure"); - DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name); if (!ret) @@ -1006,7 +1007,7 @@ sp_update_procedure(THD *thd, sp_name *name, st_sp_chistics *chistics) { int ret; DBUG_ENTER("sp_update_procedure"); - DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, chistics); if (!ret) @@ -1020,7 +1021,7 @@ sp_show_create_procedure(THD *thd, sp_name *name) { sp_head *sp; DBUG_ENTER("sp_show_create_procedure"); - DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); if ((sp= sp_find_procedure(thd, name))) { @@ -1072,7 +1073,7 @@ sp_find_function(THD *thd, sp_name *name, bool cache_only) { sp_head *sp; DBUG_ENTER("sp_find_function"); - DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); if (!(sp= sp_cache_lookup(&thd->sp_func_cache, name)) && !cache_only) @@ -1089,7 +1090,7 @@ sp_create_function(THD *thd, sp_head *sp) { int ret; DBUG_ENTER("sp_create_function"); - DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", sp->m_name.length, sp->m_name.str)); ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, sp); DBUG_RETURN(ret); @@ -1101,7 +1102,7 @@ sp_drop_function(THD *thd, sp_name *name) { int ret; DBUG_ENTER("sp_drop_function"); - DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name); if (!ret) @@ -1115,7 +1116,7 @@ sp_update_function(THD *thd, sp_name *name, st_sp_chistics *chistics) { int ret; DBUG_ENTER("sp_update_procedure"); - DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, chistics); if (!ret) @@ -1129,7 +1130,7 @@ sp_show_create_function(THD *thd, sp_name *name) { sp_head *sp; DBUG_ENTER("sp_show_create_function"); - DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str)); + DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str)); if ((sp= sp_find_function(thd, name))) { diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index 495f969eeac..fea6a67f32c 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -132,7 +132,7 @@ void sp_cache_insert(sp_cache **cp, sp_head *sp) return; // End of memory error c->version= Cversion; // No need to lock when reading long variable } - DBUG_PRINT("info",("sp_cache: inserting: %*s", sp->m_qname.length, + DBUG_PRINT("info",("sp_cache: inserting: %.*s", sp->m_qname.length, sp->m_qname.str)); c->insert(sp); *cp= c; // Update *cp if it was NULL diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 671acbc2a0c..af6acfc7448 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -280,7 +280,7 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type, DBUG_PRINT("info", ("STRING_RESULT: null")); goto return_null_item; } - DBUG_PRINT("info",("STRING_RESULT: %*s", + DBUG_PRINT("info",("STRING_RESULT: %.*s", s->length(), s->c_ptr_quick())); /* Reuse mechanism in sp_eval_func_item() is only employed for assignments @@ -354,7 +354,7 @@ sp_name::init_qname(THD *thd) return; m_qname.length= m_sroutines_key.length - 1; m_qname.str= m_sroutines_key.str + 1; - sprintf(m_qname.str, "%*s.%*s", + sprintf(m_qname.str, "%.*s.%.*s", m_db.length, (m_db.length ? m_db.str : ""), m_name.length, m_name.str); } From f577ebb88fc4f56f440ee3736b54512d528ca0a9 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Sat, 8 Oct 2005 00:57:40 +0300 Subject: [PATCH 04/13] Simple changes during review of code Added back flag that I accidently removed in last patch --- sql/ha_federated.cc | 78 +++++++++++++++------------------------------ sql/sql_prepare.cc | 2 ++ sql/sql_table.cc | 18 +++++------ 3 files changed, 37 insertions(+), 61 deletions(-) diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 49a82ec0225..258c67f476a 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -441,6 +441,7 @@ static int check_foreign_data_source( String query(query_buffer, sizeof(query_buffer), &my_charset_bin); MYSQL *mysql; DBUG_ENTER("ha_federated::check_foreign_data_source"); + /* Zero the length, otherwise the string will have misc chars */ query.length(0); @@ -525,6 +526,7 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num) char buf[FEDERATED_QUERY_BUFFER_SIZE]; int buf_len; DBUG_ENTER("ha_federated parse_url_error"); + if (share->scheme) { DBUG_PRINT("info", @@ -533,11 +535,9 @@ static int parse_url_error(FEDERATED_SHARE *share, TABLE *table, int error_num) my_free((gptr) share->scheme, MYF(0)); share->scheme= 0; } - buf_len= (table->s->connect_string.length > (FEDERATED_QUERY_BUFFER_SIZE - 1)) - ? FEDERATED_QUERY_BUFFER_SIZE - 1 : table->s->connect_string.length; - - strnmov(buf, table->s->connect_string.str, buf_len); - buf[buf_len]= '\0'; + buf_len= min(table->s->connect_string.length, + FEDERATED_QUERY_BUFFER_SIZE-1); + strmake(buf, table->s->connect_string.str, buf_len); my_error(error_num, MYF(0), buf); DBUG_RETURN(error_num); } @@ -748,12 +748,9 @@ uint ha_federated::convert_row_to_internal_format(byte *record, MYSQL_ROW row) { ulong *lengths; Field **field; - DBUG_ENTER("ha_federated::convert_row_to_internal_format"); - // num_fields= mysql_num_fields(stored_result); lengths= mysql_fetch_lengths(stored_result); - memset(record, 0, table->s->null_bytes); for (field= table->field; *field; field++) @@ -1108,8 +1105,8 @@ bool ha_federated::create_where_from_key(String *to, char tmpbuff[FEDERATED_QUERY_BUFFER_SIZE]; String tmp(tmpbuff, sizeof(tmpbuff), system_charset_info); const key_range *ranges[2]= { start_key, end_key }; - DBUG_ENTER("ha_federated::create_where_from_key"); + tmp.length(0); if (start_key == NULL && end_key == NULL) DBUG_RETURN(1); @@ -1369,8 +1366,8 @@ error: static int free_share(FEDERATED_SHARE *share) { DBUG_ENTER("free_share"); - pthread_mutex_lock(&federated_mutex); + pthread_mutex_lock(&federated_mutex); if (!--share->use_count) { if (share->scheme) @@ -1565,7 +1562,6 @@ int ha_federated::write_row(byte *buf) values_string.length(0); insert_string.length(0); insert_field_value_string.length(0); - DBUG_ENTER("ha_federated::write_row"); DBUG_PRINT("info", ("table charset name %s csname %s", @@ -1692,7 +1688,6 @@ int ha_federated::optimize(THD* thd, HA_CHECK_OPT* check_opt) { char query_buffer[STRING_BUFFER_USUAL_SIZE]; String query(query_buffer, sizeof(query_buffer), &my_charset_bin); - DBUG_ENTER("ha_federated::optimize"); query.length(0); @@ -1716,7 +1711,6 @@ int ha_federated::repair(THD* thd, HA_CHECK_OPT* check_opt) { char query_buffer[STRING_BUFFER_USUAL_SIZE]; String query(query_buffer, sizeof(query_buffer), &my_charset_bin); - DBUG_ENTER("ha_federated::repair"); query.length(0); @@ -1762,14 +1756,16 @@ int ha_federated::repair(THD* thd, HA_CHECK_OPT* check_opt) int ha_federated::update_row(const byte *old_data, byte *new_data) { /* - This used to control how the query was built. If there was a primary key, - the query would be built such that there was a where clause with only - that column as the condition. This is flawed, because if we have a multi-part - primary key, it would only use the first part! We don't need to do this anyway, - because read_range_first will retrieve the correct record, which is what is used - to build the WHERE clause. We can however use this to append a LIMIT to the end - if there is NOT a primary key. Why do this? Because we only are updating one - record, and LIMIT enforces this. + This used to control how the query was built. If there was a + primary key, the query would be built such that there was a where + clause with only that column as the condition. This is flawed, + because if we have a multi-part primary key, it would only use the + first part! We don't need to do this anyway, because + read_range_first will retrieve the correct record, which is what + is used to build the WHERE clause. We can however use this to + append a LIMIT to the end if there is NOT a primary key. Why do + this? Because we only are updating one record, and LIMIT enforces + this. */ bool has_a_primary_key= (table->s->primary_key == 0 ? TRUE : FALSE); /* @@ -1796,7 +1792,6 @@ int ha_federated::update_row(const byte *old_data, byte *new_data) String where_string(where_buffer, sizeof(where_buffer), &my_charset_bin); - DBUG_ENTER("ha_federated::update_row"); /* set string lengths to 0 to avoid misc chars in string @@ -1991,12 +1986,10 @@ int ha_federated::index_read_idx(byte *buf, uint index, const byte *key, sizeof(sql_query_buffer), &my_charset_bin); key_range range; + DBUG_ENTER("ha_federated::index_read_idx"); index_string.length(0); sql_query.length(0); - - DBUG_ENTER("ha_federated::index_read_idx"); - statistic_increment(table->in_use->status_var.ha_read_key_count, &LOCK_status); @@ -2085,8 +2078,8 @@ int ha_federated::read_range_first(const key_range *start_key, String sql_query(sql_query_buffer, sizeof(sql_query_buffer), &my_charset_bin); - DBUG_ENTER("ha_federated::read_range_first"); + if (start_key == NULL && end_key == NULL) DBUG_RETURN(0); @@ -2401,7 +2394,6 @@ void ha_federated::info(uint flag) MYSQL_RES *result= 0; MYSQL_ROW row; String status_query_string(status_buf, sizeof(status_buf), &my_charset_bin); - DBUG_ENTER("ha_federated::info"); error_code= ER_QUERY_ON_FOREIGN_DATA_SOURCE; @@ -2492,10 +2484,10 @@ error: int ha_federated::delete_all_rows() { - DBUG_ENTER("ha_federated::delete_all_rows"); - char query_buffer[FEDERATED_QUERY_BUFFER_SIZE]; String query(query_buffer, sizeof(query_buffer), &my_charset_bin); + DBUG_ENTER("ha_federated::delete_all_rows"); + query.length(0); query.set_charset(system_charset_info); @@ -2590,32 +2582,14 @@ THR_LOCK_DATA **ha_federated::store_lock(THD *thd, int ha_federated::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) { - int retval= 0; - /* - only a temporary share, to test the url - */ - FEDERATED_SHARE tmp_share; + int retval; + FEDERATED_SHARE tmp_share; // Only a temporary share, to test the url DBUG_ENTER("ha_federated::create"); - if ((retval= parse_url(&tmp_share, table_arg, 1))) - goto error; + if (!(retval= parse_url(&tmp_share, table_arg, 1))) + retval= check_foreign_data_source(&tmp_share, 1); - if ((retval= check_foreign_data_source(&tmp_share, 1))) - goto error; - - if (tmp_share.scheme) - { - my_free((gptr) tmp_share.scheme, MYF(0)); - tmp_share.scheme= 0; - } - DBUG_RETURN(retval); - -error: - if (tmp_share.scheme) - { - my_free((gptr) tmp_share.scheme, MYF(0)); - tmp_share.scheme= 0; - } + my_free((gptr) tmp_share.scheme, MYF(MY_ALLOW_ZERO_PTR)); DBUG_RETURN(retval); } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index e9777951db4..16e769438d3 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2792,6 +2792,8 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) my_error(ER_PS_NO_RECURSION, MYF(0)); return 1; } + /* In case the command has a call to SP which re-uses this statement name */ + flags|= (uint) IS_IN_USE; if (cursor && cursor->is_open()) close_cursor(); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 635b512fe23..31be8872c94 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1571,7 +1571,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, DBUG_RETURN(TRUE); } if (wait_if_global_read_lock(thd, 0, 1)) - DBUG_RETURN(error); + DBUG_RETURN(TRUE); VOID(pthread_mutex_lock(&LOCK_open)); if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { @@ -1636,20 +1636,20 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, mysql_bin_log.write(&qinfo); } error= FALSE; - goto end; - -warn: - error= 0; - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), - alias); - create_info->table_existed= 1; // Mark that table existed end: VOID(pthread_mutex_unlock(&LOCK_open)); start_waiting_global_read_lock(thd); thd->proc_info="After create"; DBUG_RETURN(error); + +warn: + error= FALSE; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR), + alias); + create_info->table_existed= 1; // Mark that table existed + goto end; } /* From 65325ecbbbdeb21102157716e533e1f89e256d4c Mon Sep 17 00:00:00 2001 From: "evgen@moonbone.local" <> Date: Mon, 10 Oct 2005 18:53:57 +0400 Subject: [PATCH 05/13] Fix bug#13327 check_equality() wasn't checking view's fields check_equality() finds equalities among field items. It checks input items to be Item_fields thus skipping view's fields, which are represented by Item_direct_view_ref. Because of this index wasn't applied in all cases it can be. To fix this problem check_equality() now takes real item of Item_direct_view_ref, except outer view refs (with depended_from set). --- mysql-test/r/view.result | 22 ++++++++++++++++++++++ mysql-test/t/view.test | 20 ++++++++++++++++++++ sql/sql_select.cc | 15 +++++++++++++++ 3 files changed, 57 insertions(+) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index e52ec950c8c..3503e885aa8 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -2298,3 +2298,25 @@ a 3 DROP VIEW v1; DROP TABLE t1; +CREATE TABLE t1 (a INT, b INT, INDEX(a,b)); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 (a INT); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +INSERT INTO t3 VALUES (1),(2),(3); +CREATE VIEW v1 AS SELECT t1.* FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b; +CREATE VIEW v2 AS SELECT t3.* FROM t1,t3 WHERE t1.a=t3.a; +EXPLAIN SELECT t1.* FROM t1 JOIN t2 WHERE t1.a=t2.a AND t1.b=t2.b AND t1.a=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 5 const 1 Using where; Using index +1 SIMPLE t2 ref a a 10 const,test.t1.b 2 Using where; Using index +EXPLAIN SELECT * FROM v1 WHERE a=1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref a a 5 const 1 Using where; Using index +1 PRIMARY t2 ref a a 10 const,test.t1.b 2 Using where; Using index +EXPLAIN SELECT * FROM v2 WHERE a=1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ref a a 5 const 1 Using where; Using index +1 PRIMARY t3 ALL NULL NULL NULL NULL 3 Using where +DROP VIEW v1,v2; +DROP TABLE t1,t2,t3; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 15c8cccf69c..5f483401cff 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -2167,3 +2167,23 @@ SELECT v_1.a FROM v1 AS v_1 GROUP BY v_1.a HAVING v_1.a IN (1,2,3); DROP VIEW v1; DROP TABLE t1; + +# +# Bug #13327 view wasn't using index for const condition +# + +CREATE TABLE t1 (a INT, b INT, INDEX(a,b)); +CREATE TABLE t2 LIKE t1; +CREATE TABLE t3 (a INT); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +INSERT INTO t2 VALUES (1,1),(2,2),(3,3); +INSERT INTO t3 VALUES (1),(2),(3); +CREATE VIEW v1 AS SELECT t1.* FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b; +CREATE VIEW v2 AS SELECT t3.* FROM t1,t3 WHERE t1.a=t3.a; +EXPLAIN SELECT t1.* FROM t1 JOIN t2 WHERE t1.a=t2.a AND t1.b=t2.b AND t1.a=1; +EXPLAIN SELECT * FROM v1 WHERE a=1; +EXPLAIN SELECT * FROM v2 WHERE a=1; +DROP VIEW v1,v2; +DROP TABLE t1,t2,t3; + + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1b1a35d2584..4b69e2c6987 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6254,6 +6254,21 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal) { Item *left_item= ((Item_func*) item)->arguments()[0]; Item *right_item= ((Item_func*) item)->arguments()[1]; + + if (left_item->type() == Item::REF_ITEM && + ((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF) + { + if (((Item_ref*)left_item)->depended_from) + return FALSE; + left_item= left_item->real_item(); + } + if (right_item->type() == Item::REF_ITEM && + ((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF) + { + if (((Item_ref*)right_item)->depended_from) + return FALSE; + right_item= right_item->real_item(); + } if (left_item->type() == Item::FIELD_ITEM && right_item->type() == Item::FIELD_ITEM && !((Item_field*)left_item)->depended_from && From cd0e0a993308231c314caf7aae2420441d71dd80 Mon Sep 17 00:00:00 2001 From: "lars@mysql.com" <> Date: Mon, 10 Oct 2005 19:23:13 +0200 Subject: [PATCH 06/13] Added missing HAVE_REPLICATION define --- sql/sql_parse.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 54d51e42895..a2ad8a414f8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2006,7 +2006,7 @@ mysql_execute_command(THD *thd) } #endif } -#endif /* !HAVE_REPLICATION */ +#endif /* HAVE_REPLICATION */ /* When option readonly is set deny operations which change tables. @@ -2841,6 +2841,7 @@ unsent_create_error: select_lex))) break; +#ifdef HAVE_REPLICATION /* Check slave filtering rules */ if (thd->slave_thread) if (all_tables_not_ok(thd,tables)) @@ -2849,6 +2850,7 @@ unsent_create_error: my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); break; } +#endif /* HAVE_REPLICATION */ res= mysql_multi_update(thd,tables, &select_lex->item_list, From 215ecd332246b0922e9f2736fbbf950b2fa5b788 Mon Sep 17 00:00:00 2001 From: "eric@mysql.com" <> Date: Mon, 10 Oct 2005 17:41:36 -0700 Subject: [PATCH 07/13] BUG#13724 conditionally added CONNECTION='connect string' for SHOW CREATE TABLE --- mysql-test/r/federated.result | 6 ++++++ mysql-test/t/federated.test | 2 ++ sql/sql_show.cc | 5 +++++ 3 files changed, 13 insertions(+) diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index e0e0bba3271..f40919a41a4 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -74,6 +74,12 @@ CREATE TABLE federated.t2 ( ) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +SHOW CREATE TABLE federated.t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(20) NOT NULL, + `name` varchar(32) NOT NULL default '' +) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:9308/federated/t1' INSERT INTO federated.t2 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t2 (id, name) VALUES (2, 'fee'); SELECT * FROM federated.t2; diff --git a/mysql-test/t/federated.test b/mysql-test/t/federated.test index c401468a940..453343e6f09 100644 --- a/mysql-test/t/federated.test +++ b/mysql-test/t/federated.test @@ -75,6 +75,8 @@ eval CREATE TABLE federated.t2 ( ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1'; +SHOW CREATE TABLE federated.t2; + INSERT INTO federated.t2 (id, name) VALUES (1, 'foo'); INSERT INTO federated.t2 (id, name) VALUES (2, 'fee'); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2d98e834de7..807b72595db 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1023,6 +1023,11 @@ store_create_info(THD *thd, TABLE_LIST *table_list, String *packet) packet->append(" COMMENT=", 9); append_unescaped(packet, share->comment, strlen(share->comment)); } + if (share->connect_string.length) + { + packet->append(" CONNECTION=", 12); + append_unescaped(packet, share->connect_string.str, share->connect_string.length); + } if (file->raid_type) { uint length; From 8d01ea1be76d87bed416778ea842175acf126834 Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Tue, 11 Oct 2005 16:26:00 +0500 Subject: [PATCH 08/13] Fix for bug#9270 multiple SSL race conditions (for 5.0 tree) The fix is needed to perform locking on shared data structures This is modification of patch proposed by Leandro Santi (see http://webs.sinectis.com.ar/lesanti/misc/mysql-4.0.23a-openssl_locking.patch) --- sql/mysqld.cc | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a6a91ac32ee..55077b22320 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -514,8 +514,22 @@ HANDLE smem_event_connect_request= 0; #include "sslopt-vars.h" #ifdef HAVE_OPENSSL +#include + +typedef struct CRYPTO_dynlock_value +{ + rw_lock_t lock; +} openssl_lock_t; + char *des_key_file; struct st_VioSSLAcceptorFd *ssl_acceptor_fd; +static openssl_lock_t *openssl_stdlocks; + +static openssl_lock_t *openssl_dynlock_create(const char *, int); +static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int); +static void openssl_lock_function(int, int, const char *, int); +static void openssl_lock(int, openssl_lock_t *, const char *, int); +static unsigned long openssl_id_function(); #endif /* HAVE_OPENSSL */ @@ -1097,6 +1111,9 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_user_conn); #ifdef HAVE_OPENSSL (void) pthread_mutex_destroy(&LOCK_des_key_file); + for (int i= 0; i < CRYPTO_num_locks(); ++i) + (void) rwlock_destroy(&openssl_stdlocks[i].lock); + OPENSSL_free(openssl_stdlocks); #endif #ifdef HAVE_REPLICATION (void) pthread_mutex_destroy(&LOCK_rpl_status); @@ -2675,10 +2692,90 @@ static int init_thread_environment() sql_print_error("Can't create thread-keys"); return 1; } +#ifdef HAVE_OPENSSL + openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() * + sizeof(openssl_lock_t)); + for (int i= 0; i < CRYPTO_num_locks(); ++i) + (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL); + CRYPTO_set_dynlock_create_callback(openssl_dynlock_create); + CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy); + CRYPTO_set_dynlock_lock_callback(openssl_lock); + CRYPTO_set_locking_callback(openssl_lock_function); + CRYPTO_set_id_callback(openssl_id_function); +#endif return 0; } +#ifdef HAVE_OPENSSL +static unsigned long openssl_id_function() +{ + return (unsigned long) pthread_self(); +} + + +static openssl_lock_t *openssl_dynlock_create(const char *file, int line) +{ + openssl_lock_t *lock= new openssl_lock_t; + my_rwlock_init(&lock->lock, NULL); + return lock; +} + + +static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file, + int line) +{ + rwlock_destroy(&lock->lock); + delete lock; +} + + +static void openssl_lock_function(int mode, int n, const char *file, int line) +{ + if (n < 0 || n > CRYPTO_num_locks()) + { + /* Lock number out of bounds. */ + sql_print_error("Fatal: OpenSSL interface problem (n = %d)", n); + abort(); + } + openssl_lock(mode, &openssl_stdlocks[n], file, line); +} + + +static void openssl_lock(int mode, openssl_lock_t *lock, const char *file, + int line) +{ + int err; + char const *what; + + switch (mode) { + case CRYPTO_LOCK|CRYPTO_READ: + what = "read lock"; + err = rw_rdlock(&lock->lock); + break; + case CRYPTO_LOCK|CRYPTO_WRITE: + what = "write lock"; + err = rw_wrlock(&lock->lock); + break; + case CRYPTO_UNLOCK|CRYPTO_READ: + case CRYPTO_UNLOCK|CRYPTO_WRITE: + what = "unlock"; + err = rw_unlock(&lock->lock); + break; + default: + /* Unknown locking mode. */ + sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode); + abort(); + } + if (err) + { + sql_print_error("Fatal: can't %s OpenSSL %s lock", what); + abort(); + } +} +#endif /* HAVE_OPENSSL */ + + static void init_ssl() { #ifdef HAVE_OPENSSL From 2456c0c6684668fc0f4675c56e061677b63464b0 Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Tue, 11 Oct 2005 15:01:38 +0200 Subject: [PATCH 09/13] Fixed BUG#13510: Setting password local variable changes current password Disallow conflicting use of variables named "password" and "names". If such a variable is declared, and "SET ... = ..." is used for them, an error is returned; the user must resolve the conflict by either using `var` (indicating that the local variable is set) or by renaming the variable. This is necessary since setting "password" and "names" are treated as special cases by the parser. --- mysql-test/r/sp-error.result | 38 ++++++++++++++++++++++++++ mysql-test/t/sp-error.test | 53 ++++++++++++++++++++++++++++++++++++ sql/share/errmsg.txt | 2 ++ sql/sql_yacc.yy | 23 ++++++++++++++++ 4 files changed, 116 insertions(+) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 05b6a2788ea..43430ca312b 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -834,3 +834,41 @@ ERROR HY000: Not allowed to set autocommit from a stored function or trigger create trigger bug12712 before insert on t1 for each row set session autocommit = 0; ERROR HY000: Not allowed to set autocommit from a stored function or trigger +drop procedure if exists bug13510_1| +drop procedure if exists bug13510_2| +drop procedure if exists bug13510_3| +drop procedure if exists bug13510_4| +create procedure bug13510_1() +begin +declare password varchar(10); +set password = 'foo1'; +select password; +end| +ERROR 42000: Variable 'password' must be quoted with `...`, or renamed +create procedure bug13510_2() +begin +declare names varchar(10); +set names = 'foo2'; +select names; +end| +ERROR 42000: Variable 'names' must be quoted with `...`, or renamed +create procedure bug13510_3() +begin +declare password varchar(10); +set `password` = 'foo3'; +select password; +end| +create procedure bug13510_4() +begin +declare names varchar(10); +set `names` = 'foo4'; +select names; +end| +call bug13510_3()| +password +foo3 +call bug13510_4()| +names +foo4 +drop procedure bug13510_3| +drop procedure bug13510_4| diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index fa74c318db3..b3caa093487 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -1212,6 +1212,59 @@ call bug9367(); drop procedure bug9367; drop table t1; --enable_parsing + +# +# BUG#13510: Setting password local variable changes current password +# +delimiter |; +--disable_warnings +drop procedure if exists bug13510_1| +drop procedure if exists bug13510_2| +drop procedure if exists bug13510_3| +drop procedure if exists bug13510_4| +--enable_warnings + +--error ER_SP_BAD_VAR_SHADOW +create procedure bug13510_1() +begin + declare password varchar(10); + + set password = 'foo1'; + select password; +end| + +--error ER_SP_BAD_VAR_SHADOW +create procedure bug13510_2() +begin + declare names varchar(10); + + set names = 'foo2'; + select names; +end| + +create procedure bug13510_3() +begin + declare password varchar(10); + + set `password` = 'foo3'; + select password; +end| + +create procedure bug13510_4() +begin + declare names varchar(10); + + set `names` = 'foo4'; + select names; +end| + +call bug13510_3()| +call bug13510_4()| + +drop procedure bug13510_3| +drop procedure bug13510_4| +delimiter ;| + # # BUG#NNNN: New bug synopsis # diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index 10f0d0691d1..ccf11248a1f 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -5420,3 +5420,5 @@ ER_ROW_IS_REFERENCED_2 23000 eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)" ER_NO_REFERENCED_ROW_2 23000 eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)" +ER_SP_BAD_VAR_SHADOW 42000 + eng "Variable '%-.64s' must be quoted with `...`, or renamed" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f28fbe5c803..447530d633b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -7992,6 +7992,18 @@ option_value: $2= $2 ? $2: global_system_variables.character_set_client; lex->var_list.push_back(new set_var_collation_client($2,thd->variables.collation_database,$2)); } + | NAMES_SYM equal expr + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + LEX_STRING names; + + names.str= (char *)"names"; + names.length= 5; + if (spc && spc->find_pvar(&names)) + my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str); + YYABORT; + } | NAMES_SYM charset_name_or_default opt_collate { LEX *lex= Lex; @@ -8009,6 +8021,17 @@ option_value: { THD *thd=YYTHD; LEX_USER *user; + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + LEX_STRING pw; + + pw.str= (char *)"password"; + pw.length= 8; + if (spc && spc->find_pvar(&pw)) + { + my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str); + YYABORT; + } if (!(user=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) YYABORT; user->host=null_lex_str; From 8782f5a0e3577ae515e0e77503a0cd86fc95dfe4 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Tue, 11 Oct 2005 21:16:08 +0200 Subject: [PATCH 10/13] - added Docs/manual.chm to the windows source distribution (BUG#13899) --- scripts/make_win_src_distribution.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh index 0800fec1ac6..f863e5385d4 100644 --- a/scripts/make_win_src_distribution.sh +++ b/scripts/make_win_src_distribution.sh @@ -275,7 +275,7 @@ cd $SOURCE for i in COPYING ChangeLog README EXCEPTIONS-CLIENT\ INSTALL-SOURCE INSTALL-WIN \ INSTALL-WIN-SOURCE \ - Docs/INSTALL-BINARY + Docs/INSTALL-BINARY Docs/manual.chm do print_debug "Copying file '$i'" From f5fdf3e87a5f60fdb6442912ae5741a24b2461c8 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Wed, 12 Oct 2005 00:58:22 +0300 Subject: [PATCH 11/13] Reviewing new pushed code - CHAR() now returns binary string as default - CHAR(X*65536+Y*256+Z) is now equal to CHAR(X,Y,Z) independent of the character set for CHAR() - Test for both ETIMEDOUT and ETIME from pthread_cond_timedwait() (Some old systems returns ETIME and it's safer to test for both values than to try to write a wrapper for each old system) - Fixed new introduced bug in NOT BETWEEN X and X - Ensure we call commit_by_xid or rollback_by_xid for all engines, even if one engine has failed - Use octet2hex() for all conversion of string to hex - Simplify and optimize code --- client/mysqldump.c | 71 +++++---- client/mysqltest.c | 8 +- include/mysql_com.h | 2 +- mysql-test/r/ctype_utf8.result | 34 ++-- mysql-test/r/func_str.result | 7 +- mysql-test/r/range.result | 7 + mysql-test/r/user_var-binlog.result | 4 +- mysql-test/r/view.result | 13 +- mysql-test/t/ctype_utf8.test | 6 +- mysql-test/t/func_str.test | 1 + mysql-test/t/range.test | 5 + mysql-test/t/view.test | 11 +- mysys/mf_keycache.c | 17 +- mysys/my_os2cond.c | 147 ++++++++---------- mysys/thr_lock.c | 9 +- mysys/thr_mutex.c | 2 +- server-tools/instance-manager/instance.cc | 2 +- .../instance-manager/thread_registry.cc | 13 +- sql/ha_federated.cc | 9 +- sql/ha_ndbcluster.cc | 7 +- sql/handler.cc | 27 ++-- sql/item.h | 2 +- sql/item_func.cc | 103 +++++++----- sql/item_strfunc.cc | 42 ++--- sql/item_strfunc.h | 2 +- sql/log_event.cc | 18 +-- sql/parse_file.cc | 7 +- sql/password.c | 13 +- sql/slave.cc | 2 +- sql/sql_base.cc | 4 +- sql/sql_insert.cc | 2 +- sql/sql_manager.cc | 12 +- sql/sql_parse.cc | 11 +- sql/sql_prepare.cc | 2 +- sql/sql_select.cc | 8 +- sql/sql_show.cc | 3 - sql/sql_table.cc | 7 +- sql/sql_view.cc | 2 +- sql/unireg.cc | 8 +- 39 files changed, 334 insertions(+), 316 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 95238df30c7..21933ab03f2 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -30,7 +30,7 @@ ** master/autocommit code by Brian Aker ** SSL by ** Andrei Errapart -** Tõnu Samuel +** Tõnu Samuel ** XML by Gary Huntress 10/10/01, cleaned up ** and adapted to mysqldump 05/11/01 by Jani Tolonen ** Added --single-transaction option 06/06/2002 by Peter Zaitsev @@ -1287,7 +1287,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, { MYSQL_RES *tableRes; MYSQL_ROW row; - my_bool init=0; + my_bool init=0, delayed, write_data, complete_insert; uint num_fields; char *result_table, *opt_quoted_table; const char *insert_option; @@ -1296,31 +1296,33 @@ static uint get_table_structure(char *table, char *db, char *table_type, char query_buff[512]; FILE *sql_file = md_result_file; int len; - DBUG_ENTER("get_table_structure"); - DBUG_PRINT("enter", ("db: %s, table: %s", db, table)); + DBUG_PRINT("enter", ("db: %s table: %s", db, table)); *ignore_flag= check_if_ignore_table(table, table_type); - if (opt_delayed && (*ignore_flag & IGNORE_INSERT_DELAYED)) + delayed= opt_delayed; + if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED)) + { + delayed= 0; if (verbose) fprintf(stderr, - "-- Unable to use delayed inserts for table '%s' because it's of\ - type %s\n", table, table_type); + "-- Warning: Unable to use delayed inserts for table '%s' " + "because it's of type %s\n", table, table_type); + } - if (!(*ignore_flag & IGNORE_DATA)) + complete_insert= 0; + if ((write_data= !(*ignore_flag & IGNORE_DATA))) { + complete_insert= opt_complete_insert; if (!insert_pat_inited) insert_pat_inited= init_dynamic_string(&insert_pat, "", 1024, 1024); else dynstr_set(&insert_pat, ""); } - insert_option= ((opt_delayed && opt_ignore && - !(*ignore_flag & IGNORE_INSERT_DELAYED)) ? - " DELAYED IGNORE " : - opt_delayed && !(*ignore_flag & IGNORE_INSERT_DELAYED) ? " DELAYED " : - opt_ignore ? " IGNORE " : ""); + insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " : + delayed ? " DELAYED " : opt_ignore ? " IGNORE " : ""); if (verbose) fprintf(stderr, "-- Retrieving table structure for table %s...\n", table); @@ -1452,17 +1454,18 @@ static uint get_table_structure(char *table, char *db, char *table_type, } /* - if *ignore_flag & IGNORE_DATA is true, then we don't build up insert statements - for the table's data. Note: in subsequent lines of code, this test will - have to be performed each time we are appending to insert_pat. + If write_data is true, then we build up insert statements for + the table's data. Note: in subsequent lines of code, this test + will have to be performed each time we are appending to + insert_pat. */ - if (!(*ignore_flag & IGNORE_DATA)) + if (write_data) { dynstr_append_mem(&insert_pat, "INSERT ", 7); dynstr_append(&insert_pat, insert_option); dynstr_append_mem(&insert_pat, "INTO ", 5); dynstr_append(&insert_pat, opt_quoted_table); - if (opt_complete_insert) + if (complete_insert) { dynstr_append_mem(&insert_pat, " (", 2); } @@ -1476,15 +1479,16 @@ static uint get_table_structure(char *table, char *db, char *table_type, while ((row=mysql_fetch_row(tableRes))) { - if (init) + if (complete_insert) { - if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA)) + if (init) + { dynstr_append_mem(&insert_pat, ", ", 2); - } - init=1; - if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA)) + } + init=1; dynstr_append(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); + } } num_fields= (uint) mysql_num_rows(tableRes); mysql_free_result(tableRes); @@ -1532,7 +1536,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, check_io(sql_file); } - if (!(*ignore_flag & IGNORE_DATA)) + if (write_data) { dynstr_append_mem(&insert_pat, "INSERT ", 7); dynstr_append(&insert_pat, insert_option); @@ -1558,11 +1562,11 @@ static uint get_table_structure(char *table, char *db, char *table_type, fputs(",\n",sql_file); check_io(sql_file); } - if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA)) + if (complete_insert) dynstr_append_mem(&insert_pat, ", ", 2); } init=1; - if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA)) + if (opt_complete_insert) dynstr_append(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); if (!tFlag) @@ -1723,7 +1727,7 @@ continue_xml: check_io(sql_file); } } - if (opt_complete_insert && !(*ignore_flag & IGNORE_DATA)) + if (opt_complete_insert) { dynstr_append_mem(&insert_pat, ") VALUES ", 9); if (!extended_insert) @@ -1877,7 +1881,7 @@ static void dump_table(char *table, char *db) { char ignore_flag; char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3]; - char table_type[NAME_LEN]; + char table_type[NAME_LEN]; char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table; char *query= query_buf; int error= 0; @@ -1892,7 +1896,7 @@ static void dump_table(char *table, char *db) Make sure you get the create table info before the following check for --no-data flag below. Otherwise, the create table info won't be printed. */ - num_fields= get_table_structure(table, db, (char *)&table_type, &ignore_flag); + num_fields= get_table_structure(table, db, table_type, &ignore_flag); /* Check --no-data flag */ if (dFlag) @@ -1904,7 +1908,9 @@ static void dump_table(char *table, char *db) DBUG_VOID_RETURN; } - DBUG_PRINT("info", ("ignore_flag %x num_fields %d", ignore_flag, num_fields)); + DBUG_PRINT("info", + ("ignore_flag: %x num_fields: %d", (int) ignore_flag, + num_fields)); /* If the table type is a merge table or any type that has to be _completely_ ignored and no data dumped @@ -1913,7 +1919,7 @@ static void dump_table(char *table, char *db) { if (verbose) fprintf(stderr, - "-- Skipping data for table '%s' because it's of type %s\n", + "-- Warning: Skipping data for table '%s' because it's of type %s\n", table, table_type); DBUG_VOID_RETURN; } @@ -1930,7 +1936,6 @@ static void dump_table(char *table, char *db) result_table= quote_name(table,table_buff, 1); opt_quoted_table= quote_name(table, table_buff2, 0); - if (verbose) fprintf(stderr, "-- Sending SELECT query...\n"); if (path) @@ -2992,7 +2997,7 @@ char check_if_ignore_table(const char *table_name, char *table_type) DBUG_RETURN(result); /* assume table is ok */ } if (!(row[1])) - strmake(table_type,"VIEW", NAME_LEN-1); + strmake(table_type, "VIEW", NAME_LEN-1); else { /* diff --git a/client/mysqltest.c b/client/mysqltest.c index e0507d056a6..6653d24e575 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -737,9 +737,7 @@ err: static int check_result(DYNAMIC_STRING* ds, const char *fname, my_bool require_option) { - int error= RESULT_OK; int res= dyn_string_cmp(ds, fname); - DBUG_ENTER("check_result"); if (res && require_option) @@ -749,18 +747,16 @@ static int check_result(DYNAMIC_STRING* ds, const char *fname, break; /* ok */ case RESULT_LENGTH_MISMATCH: verbose_msg("Result length mismatch"); - error= RESULT_LENGTH_MISMATCH; break; case RESULT_CONTENT_MISMATCH: verbose_msg("Result content mismatch"); - error= RESULT_CONTENT_MISMATCH; break; default: /* impossible */ die("Unknown error code from dyn_string_cmp()"); } - if (error) + if (res != RESULT_OK) reject_dump(fname, ds->str, ds->length); - DBUG_RETURN(error); + DBUG_RETURN(res); } diff --git a/include/mysql_com.h b/include/mysql_com.h index c4eb33a6c9a..1e595cdbba3 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -409,7 +409,7 @@ my_bool check_scramble(const char *reply, const char *message, const unsigned char *hash_stage2); void get_salt_from_password(unsigned char *res, const char *password); void make_password_from_salt(char *to, const unsigned char *hash_stage2); -void octet2hex(char *to, const unsigned char *str, unsigned int len); +char *octet2hex(char *to, const char *str, unsigned int len); /* end of password.c */ diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 1695f1c67e8..5516be88b75 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1079,29 +1079,31 @@ char(53647) select char(0xff,0x8f); char(0xff,0x8f) -Warnings: -Warning 1300 Invalid utf8 character string: 'FF8F' set sql_mode=traditional; select char(0xff,0x8f); char(0xff,0x8f) -NULL -Warnings: -Error 1300 Invalid utf8 character string: 'FF8F' + +select convert(char(0xff,0x8f) using utf8); +convert(char(0xff,0x8f) using utf8) + select char(195); char(195) -NULL -Warnings: -Error 1300 Invalid utf8 character string: 'C3' + +select convert(char(195) using utf8); +convert(char(195) using utf8) + select char(196); char(196) -NULL -Warnings: -Error 1300 Invalid utf8 character string: 'C4' -select char(2557); -char(2557) -NULL -Warnings: -Error 1300 Invalid utf8 character string: 'FD' + +select convert(char(196) using utf8); +convert(char(196) using utf8) + +select hex(char(2557)); +hex(char(2557)) +09FD +select hex(convert(char(2557) using utf8)); +hex(convert(char(2557) using utf8)) +09FD set names utf8; create table t1 (a char(1)) default character set utf8; create table t2 (a char(1)) default character set utf8; diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index d250d2fce84..a305bf20bff 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -21,6 +21,9 @@ length(_latin1'\n\t\n\b\0\\_\\%\\') select concat('monty',' was here ','again'),length('hello'),char(ascii('h')),ord('h'); concat('monty',' was here ','again') length('hello') char(ascii('h')) ord('h') monty was here again 5 h 104 +select hex(char(256)); +hex(char(256)) +0100 select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ; locate('he','hello') locate('he','hello',2) locate('lo','hello',2) 1 0 4 @@ -598,7 +601,7 @@ collation(hex(130)) coercibility(hex(130)) latin1_swedish_ci 4 select collation(char(130)), coercibility(hex(130)); collation(char(130)) coercibility(hex(130)) -latin1_swedish_ci 4 +binary 4 select collation(format(130,10)), coercibility(format(130,10)); collation(format(130,10)) coercibility(format(130,10)) latin1_swedish_ci 4 @@ -720,7 +723,7 @@ t1 CREATE TABLE `t1` ( `oct(130)` varchar(64) NOT NULL default '', `conv(130,16,10)` varchar(64) NOT NULL default '', `hex(130)` varchar(6) NOT NULL default '', - `char(130)` varchar(1) NOT NULL default '', + `char(130)` varbinary(1) NOT NULL default '', `format(130,10)` varchar(4) NOT NULL default '', `left(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '', `right(_latin2'a',1)` varchar(1) character set latin2 NOT NULL default '', diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index 69c150fc0b7..6dedd020249 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -809,4 +809,11 @@ id select_type table type possible_keys key key_len ref rows Extra explain select * from t2 where a = 'a' or a='a '; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ref a a 13 const # Using where +update t1 set a='b' where a<>'a'; +explain select * from t1 where a not between 'b' and 'b'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 13 NULL # Using where +select * from t1 where a not between 'b' and 'b'; +a filler +a drop table t1,t2,t3; diff --git a/mysql-test/r/user_var-binlog.result b/mysql-test/r/user_var-binlog.result index 17ac8809d52..700ec7b09e0 100644 --- a/mysql-test/r/user_var-binlog.result +++ b/mysql-test/r/user_var-binlog.result @@ -11,7 +11,7 @@ Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 98 User var 1 139 @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci master-bin.000001 139 Query 1 231 use `test`; INSERT INTO t1 VALUES(@`a b`) master-bin.000001 231 User var 1 273 @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci -master-bin.000001 273 User var 1 311 @`var2`=_latin1 0x61 COLLATE latin1_swedish_ci +master-bin.000001 273 User var 1 311 @`var2`=_binary 0x61 COLLATE binary master-bin.000001 311 Query 1 411 use `test`; insert into t1 values (@var1),(@var2) /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; @@ -24,7 +24,7 @@ SET @@session.sql_mode=0; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8; INSERT INTO t1 VALUES(@`a b`); SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`; -SET @`var2`:=_latin1 0x61 COLLATE `latin1_swedish_ci`; +SET @`var2`:=_binary 0x61 COLLATE `binary`; SET TIMESTAMP=10000; insert into t1 values (@var1),(@var2); # End of log file diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index e52ec950c8c..14187703ca3 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -847,13 +847,16 @@ cast(1 as char(3)) drop view v1; create table t1 (a int); create view v1 as select a from t1; -create database seconddb; -rename table v1 to seconddb.v1; -ERROR HY000: Changing schema from 'test' to 'seconddb' is not allowed. +create view v3 as select a from t1; +create database mysqltest; +rename table v1 to mysqltest.v1; +ERROR HY000: Changing schema from 'test' to 'mysqltest' is not allowed. rename table v1 to v2; +rename table v3 to v1, v2 to t1; +ERROR 42S01: Table 't1' already exists drop table t1; -drop view v2; -drop database seconddb; +drop view v2,v3; +drop database mysqltest; create view v1 as select 'a',1; create view v2 as select * from v1 union all select * from v1; create view v3 as select * from v2 where 1 = (select `1` from v2); diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 8194dbdb438..d186ca8a1f6 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -880,9 +880,13 @@ select char(0xff,0x8f); # incorrect value in strict mode: return NULL with "Error" level warning set sql_mode=traditional; select char(0xff,0x8f); +select convert(char(0xff,0x8f) using utf8); select char(195); +select convert(char(195) using utf8); select char(196); -select char(2557); +select convert(char(196) using utf8); +select hex(char(2557)); +select hex(convert(char(2557) using utf8)); # # Bug#12891: UNION doesn't return DISTINCT result for multi-byte characters diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 6cd27903a42..ac2bf820257 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -15,6 +15,7 @@ select bit_length('\n\t\r\b\0\_\%\\'); select char_length('\n\t\r\b\0\_\%\\'); select length(_latin1'\n\t\n\b\0\\_\\%\\'); select concat('monty',' was here ','again'),length('hello'),char(ascii('h')),ord('h'); +select hex(char(256)); select locate('he','hello'),locate('he','hello',2),locate('lo','hello',2) ; select instr('hello','HE'), instr('hello',binary 'HE'), instr(binary 'hello','HE'); select position(binary 'll' in 'hello'),position('a' in binary 'hello'); diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 11c5e8d7bc5..89376d33f61 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -625,4 +625,9 @@ explain select * from t2 where a between 'a' and 'a '; --replace_column 9 # explain select * from t2 where a = 'a' or a='a '; +update t1 set a='b' where a<>'a'; +--replace_column 9 # +explain select * from t1 where a not between 'b' and 'b'; +select * from t1 where a not between 'b' and 'b'; + drop table t1,t2,t3; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 15c8cccf69c..f49191130f5 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -790,13 +790,16 @@ drop view v1; # create table t1 (a int); create view v1 as select a from t1; -create database seconddb; +create view v3 as select a from t1; +create database mysqltest; -- error 1450 -rename table v1 to seconddb.v1; +rename table v1 to mysqltest.v1; rename table v1 to v2; +--error 1050 +rename table v3 to v1, v2 to t1; drop table t1; -drop view v2; -drop database seconddb; +drop view v2,v3; +drop database mysqltest; # # bug handling from VIEWs diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 69410e9faaa..3b5e277b56d 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -2750,9 +2750,12 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond, gettimeofday(&now, &tz); /* Prepare timeout value */ timeout.tv_sec= now.tv_sec + KEYCACHE_TIMEOUT; - timeout.tv_nsec= now.tv_usec * 1000; /* timeval uses microseconds. */ - /* timespec uses nanoseconds. */ - /* 1 nanosecond = 1000 micro seconds. */ + /* + timeval uses microseconds. + timespec uses nanoseconds. + 1 nanosecond = 1000 micro seconds + */ + timeout.tv_nsec= now.tv_usec * 1000; KEYCACHE_THREAD_TRACE_END("started waiting"); #if defined(KEYCACHE_DEBUG) cnt++; @@ -2762,17 +2765,15 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond, #endif rc= pthread_cond_timedwait(cond, mutex, &timeout); KEYCACHE_THREAD_TRACE_BEGIN("finished waiting"); -#if defined(KEYCACHE_DEBUG) - if (rc == ETIMEDOUT) + if (rc == ETIMEDOUT || rc == ETIME) { +#if defined(KEYCACHE_DEBUG) fprintf(keycache_debug_log,"aborted by keycache timeout\n"); fclose(keycache_debug_log); abort(); - } #endif - - if (rc == ETIMEDOUT) keycache_dump(); + } #if defined(KEYCACHE_DEBUG) KEYCACHE_DBUG_ASSERT(rc != ETIMEDOUT); diff --git a/mysys/my_os2cond.c b/mysys/my_os2cond.c index 83a03d62046..bf3e85c26a9 100644 --- a/mysys/my_os2cond.c +++ b/mysys/my_os2cond.c @@ -22,7 +22,7 @@ ** The following is a simple implementation of posix conditions *****************************************************************************/ -#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */ +#undef SAFE_MUTEX /* Avoid safe_mutex redefinitions */ #include "mysys_priv.h" #if defined(THREAD) && defined(OS2) #include @@ -31,134 +31,109 @@ int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) { - APIRET rc = 0; - HEV event; - cond->waiting=0; - /* Warp3 FP29 or Warp4 FP4 or better required */ - rc = DosCreateEventSem( NULL, &cond->semaphore, 0x0800, 0); - if (rc) - return ENOMEM; - + cond->waiting= 0; + /* Warp3 FP29 or Warp4 FP4 or better required */ + if (DosCreateEventSem(NULL, &cond->semaphore, 0x0800, 0)) + return ENOMEM; return 0; } int pthread_cond_destroy(pthread_cond_t *cond) { - APIRET rc; - - do { - rc = DosCloseEventSem(cond->semaphore); - if (rc == 301) DosPostEventSem(cond->semaphore); - } while (rc == 301); - if (rc) - return EINVAL; - - return 0; + for (;;) + { + APIRET rc; + if ((rc= DosCloseEventSem(cond->semaphore)) != 301) + return rc ? EINVAL : 0; + DosPostEventSem(cond->semaphore); + } } int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { - APIRET rc; - int rval; - - rval = 0; - cond->waiting++; - - if (mutex) pthread_mutex_unlock(mutex); - - rc = DosWaitEventSem(cond->semaphore,SEM_INDEFINITE_WAIT); - if (rc != 0) - rval = EINVAL; - - if (mutex) pthread_mutex_lock(mutex); - - cond->waiting--; - - return rval; + int rval= 0; + cond->waiting++; + if (mutex) + pthread_mutex_unlock(mutex); + if (DosWaitEventSem(cond->semaphore, SEM_INDEFINITE_WAIT)) + rval= EINVAL; + if (mutex) + pthread_mutex_lock(mutex); + cond->waiting--; + return rval; } int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - struct timespec *abstime) + struct timespec *abstime) { struct timeb curtime; int result; long timeout; - APIRET rc; - int rval; + int rval= 0; - _ftime(&curtime); - timeout= ((long) (abstime->ts_sec - curtime.time)*1000L + - (long)((abstime->ts_nsec/1000) - curtime.millitm)/1000L); - if (timeout < 0) /* Some safety */ - timeout = 0L; + _ftime(&curtime); + timeout= ((long) (abstime->ts_sec - curtime.time) * 1000L + + (long) ((abstime->ts_nsec / 1000) - curtime.millitm) / 1000L); + if (timeout < 0) /* Some safety */ + timeout= 0L; - rval = 0; - cond->waiting++; + cond->waiting++; - if (mutex) pthread_mutex_unlock(mutex); + if (mutex) + pthread_mutex_unlock(mutex); + if (DosWaitEventSem(cond->semaphore, timeout) != 0) + rval= ETIMEDOUT; + if (mutex) + pthread_mutex_lock(mutex); - rc = DosWaitEventSem(cond->semaphore, timeout); - if (rc != 0) - rval= ETIMEDOUT; + cond->waiting--; - if (mutex) pthread_mutex_lock(mutex); - - cond->waiting--; - - return rval; + return rval; } int pthread_cond_signal(pthread_cond_t *cond) { - APIRET rc; - - /* Bring the next thread off the condition queue: */ - rc = DosPostEventSem(cond->semaphore); - return 0; + /* Bring the next thread off the condition queue: */ + DosPostEventSem(cond->semaphore); + return 0; } int pthread_cond_broadcast(pthread_cond_t *cond) { - int i; - APIRET rc; - - /* - * Enter a loop to bring all threads off the - * condition queue: - */ - i = cond->waiting; - while (i--) rc = DosPostEventSem(cond->semaphore); - - return 0 ; + int i; + /* Enter a loop to bring all threads off the condition queue */ + for (i= cond->waiting; i--;) + DosPostEventSem(cond->semaphore); + return 0; } int pthread_attr_init(pthread_attr_t *connect_att) { - connect_att->dwStackSize = 0; - connect_att->dwCreatingFlag = 0; - connect_att->priority = 0; + connect_att->dwStackSize= 0; + connect_att->dwCreatingFlag= 0; + connect_att->priority= 0; return 0; } -int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack) +int pthread_attr_setstacksize(pthread_attr_t *connect_att, DWORD stack) { - connect_att->dwStackSize=stack; + connect_att->dwStackSize= stack; return 0; } -int pthread_attr_setprio(pthread_attr_t *connect_att,int priority) +int pthread_attr_setprio(pthread_attr_t *connect_att, int priority) { - connect_att->priority=priority; + connect_att->priority= priority; return 0; } int pthread_attr_destroy(pthread_attr_t *connect_att) { - bzero((gptr) connect_att,sizeof(*connect_att)); + bzero((gptr) connect_att, sizeof(*connect_att)); return 0; } @@ -166,22 +141,22 @@ int pthread_attr_destroy(pthread_attr_t *connect_att) ** Fix localtime_r() to be a bit safer ****************************************************************************/ -struct tm *localtime_r(const time_t *timep,struct tm *tmp) +struct tm *localtime_r(const time_t *timep, struct tm *tmp) { - if (*timep == (time_t) -1) /* This will crash win32 */ + if (*timep == (time_t) - 1) /* This will crash win32 */ { - bzero(tmp,sizeof(*tmp)); + bzero(tmp, sizeof(*tmp)); } else { - struct tm *res=localtime(timep); - if (!res) /* Wrong date */ + struct tm *res= localtime(timep); + if (!res) /* Wrong date */ { - bzero(tmp,sizeof(*tmp)); /* Keep things safe */ + bzero(tmp, sizeof(*tmp)); /* Keep things safe */ return 0; } *tmp= *res; } return tmp; } -#endif /* __WIN__ */ +#endif /* __WIN__ */ diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 41266d61b0a..f5a8b618949 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -408,9 +408,10 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, set_timespec(wait_timeout, table_lock_wait_timeout); while (!thread_var->abort || in_wait_list) { - int rc= can_deadlock ? pthread_cond_timedwait(cond, &data->lock->mutex, - &wait_timeout) : - pthread_cond_wait(cond, &data->lock->mutex); + int rc= (can_deadlock ? + pthread_cond_timedwait(cond, &data->lock->mutex, + &wait_timeout) : + pthread_cond_wait(cond, &data->lock->mutex)); /* We must break the wait if one of the following occurs: - the connection has been aborted (!thread_var->abort), but @@ -426,7 +427,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, */ if (data->cond == 0) break; - if (rc == ETIMEDOUT) + if (rc == ETIMEDOUT || rc == ETIME) { result= THR_LOCK_WAIT_TIMEOUT; break; diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index 2facb4e18cf..3326068d164 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -239,7 +239,7 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, pthread_mutex_unlock(&mp->global); error=pthread_cond_timedwait(cond,&mp->mutex,abstime); #ifdef EXTRA_DEBUG - if (error && (error != EINTR && error != ETIMEDOUT)) + if (error && (error != EINTR && error != ETIMEDOUT && error != ETIME)) { fprintf(stderr,"safe_mutex: Got error: %d (%d) when doing a safe_mutex_timedwait at %s, line %d\n", error, errno, file, line); } diff --git a/server-tools/instance-manager/instance.cc b/server-tools/instance-manager/instance.cc index 0c3c1aee5b4..0b781a6119c 100644 --- a/server-tools/instance-manager/instance.cc +++ b/server-tools/instance-manager/instance.cc @@ -474,7 +474,7 @@ int Instance::stop() status= pthread_cond_timedwait(&COND_instance_stopped, &LOCK_instance, &timeout); - if (status == ETIMEDOUT) + if (status == ETIMEDOUT || status == ETIME) break; } diff --git a/server-tools/instance-manager/thread_registry.cc b/server-tools/instance-manager/thread_registry.cc index fe665f410e5..f9b98eacbee 100644 --- a/server-tools/instance-manager/thread_registry.cc +++ b/server-tools/instance-manager/thread_registry.cc @@ -145,6 +145,7 @@ int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *wait_time) { + int rc; pthread_mutex_lock(&LOCK_thread_registry); if (shutdown_in_progress) { @@ -154,7 +155,8 @@ int Thread_registry::cond_timedwait(Thread_info *info, pthread_cond_t *cond, info->current_cond= cond; pthread_mutex_unlock(&LOCK_thread_registry); /* sic: race condition here, cond can be signaled in deliver_shutdown */ - int rc= pthread_cond_timedwait(cond, mutex, wait_time); + if ((rc= pthread_cond_timedwait(cond, mutex, wait_time)) == ETIME) + rc= ETIMEDOUT; // For easier usage pthread_mutex_lock(&LOCK_thread_registry); info->current_cond= 0; pthread_mutex_unlock(&LOCK_thread_registry); @@ -172,6 +174,7 @@ void Thread_registry::deliver_shutdown() { Thread_info *info; struct timespec shutdown_time; + int error; set_timespec(shutdown_time, 1); pthread_mutex_lock(&LOCK_thread_registry); @@ -204,11 +207,13 @@ void Thread_registry::deliver_shutdown() released - the only case when the predicate is false is when no other threads exist. */ - while (pthread_cond_timedwait(&COND_thread_registry_is_empty, - &LOCK_thread_registry, - &shutdown_time) != ETIMEDOUT && + while (((error= pthread_cond_timedwait(&COND_thread_registry_is_empty, + &LOCK_thread_registry, + &shutdown_time)) != ETIMEDOUT && + error != ETIME) && head.next != &head) ; + /* If previous signals did not reach some threads, they must be sleeping in pthread_cond_wait or in a blocking syscall. Wake them up: diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 20badb05f09..3c5adb3f10f 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -821,13 +821,8 @@ static bool emit_key_part_element(String *to, KEY_PART_INFO *part, *buf++= '0'; *buf++= 'x'; - for (; len; ptr++,len--) - { - uint tmp= (uint)(uchar) *ptr; - *buf++= _dig_vec_upper[tmp >> 4]; - *buf++= _dig_vec_upper[tmp & 15]; - } - if (to->append(buff, (uint)(buf - buff))) + buf= octet2hex(buf, (char*) ptr, len); + if (to->append((char*) buff, (uint)(buf - buff))) DBUG_RETURN(1); } else if (part->key_part_flag & HA_BLOB_PART) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 6f2c7670b88..50f53ecf410 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -5931,7 +5931,6 @@ extern "C" pthread_handler_decl(ndb_util_thread_func, { THD *thd; /* needs to be first for thread_stack */ Ndb* ndb; - int error= 0; struct timespec abstime; my_thread_init(); @@ -5960,9 +5959,9 @@ extern "C" pthread_handler_decl(ndb_util_thread_func, { pthread_mutex_lock(&LOCK_ndb_util_thread); - error= pthread_cond_timedwait(&COND_ndb_util_thread, - &LOCK_ndb_util_thread, - &abstime); + pthread_cond_timedwait(&COND_ndb_util_thread, + &LOCK_ndb_util_thread, + &abstime); pthread_mutex_unlock(&LOCK_ndb_util_thread); DBUG_PRINT("ndb_util_thread", ("Started, ndb_cache_check_time: %d", diff --git a/sql/handler.cc b/sql/handler.cc index d449a0b90f2..1e38b6dc2ab 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -209,6 +209,8 @@ retest: return DB_TYPE_UNKNOWN; } + + const char *ha_get_storage_engine(enum db_type db_type) { handlerton **types; @@ -217,25 +219,19 @@ const char *ha_get_storage_engine(enum db_type db_type) if (db_type == (*types)->db_type) return (*types)->name; } - - return "none"; + return "*NONE*"; } + bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag) { handlerton **types; for (types= sys_table_types; *types; types++) { if (db_type == (*types)->db_type) - { - if ((*types)->flags & flag) - return TRUE; - else - return FALSE; - } + return test((*types)->flags & flag); } - - return FALSE; + return FALSE; // No matching engine } @@ -850,18 +846,25 @@ int ha_autocommit_or_rollback(THD *thd, int error) DBUG_RETURN(error); } + int ha_commit_or_rollback_by_xid(XID *xid, bool commit) { handlerton **types; int res= 1; for (types= sys_table_types; *types; types++) + { if ((*types)->state == SHOW_OPTION_YES && (*types)->recover) - res= res && - (*(commit ? (*types)->commit_by_xid : (*types)->rollback_by_xid))(xid); + { + if ((*(commit ? (*types)->commit_by_xid : + (*types)->rollback_by_xid))(xid)); + res= 0; + } + } return res; } + #ifndef DBUG_OFF /* this does not need to be multi-byte safe or anything */ static char* xid_to_str(char *buf, XID *xid) diff --git a/sql/item.h b/sql/item.h index 8e6b4e245d2..320591d4d99 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1616,7 +1616,7 @@ public: } Item *real_item() { - return (ref && *ref) ? (*ref)->real_item() : this; + return ref ? (*ref)->real_item() : this; } bool walk(Item_processor processor, byte *arg) { return (*ref)->walk(processor, arg); } diff --git a/sql/item_func.cc b/sql/item_func.cc index ef896ca3cfd..b716f56f21f 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -32,6 +32,11 @@ #include "sp_rcontext.h" #include "sp.h" +#ifdef NO_EMBEDDED_ACCESS_CHECKS +#define sp_restore_security_context(A,B) while (0) {} +#endif + + bool check_reserved_words(LEX_STRING *name) { if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") || @@ -3028,9 +3033,13 @@ void debug_sync_point(const char* lock_name, uint lock_timeout) thd->mysys_var->current_cond= &ull->cond; set_timespec(abstime,lock_timeout); - while (!thd->killed && - pthread_cond_timedwait(&ull->cond, &LOCK_user_locks, - &abstime) != ETIMEDOUT && ull->locked) ; + while (ull->locked && !thd->killed) + { + int error= pthread_cond_timedwait(&ull->cond, &LOCK_user_locks, &abstime); + if (error == ETIMEDOUT || error == ETIME) + break; + } + if (ull->locked) { if (!--ull->count) @@ -3074,7 +3083,7 @@ longlong Item_func_get_lock::val_int() struct timespec abstime; THD *thd=current_thd; User_level_lock *ull; - int error=0; + int error; /* In slave thread no need to get locks, everything is serialized. Anyway @@ -3130,22 +3139,29 @@ longlong Item_func_get_lock::val_int() thd->mysys_var->current_cond= &ull->cond; set_timespec(abstime,timeout); - while (!thd->killed && - (error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime)) - != ETIMEDOUT && error != EINVAL && ull->locked) ; - if (thd->killed) - error=EINTR; // Return NULL + error= 0; + while (ull->locked && !thd->killed) + { + error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime); + if (error == ETIMEDOUT || error == ETIME) + break; + error= 0; + } + if (ull->locked) { if (!--ull->count) + { + DBUG_ASSERT(0); delete ull; // Should never happen - if (error != ETIMEDOUT) + } + if (!error) // Killed (thd->killed != 0) { error=1; null_value=1; // Return NULL } } - else + else // We got the lock { ull->locked=1; ull->thread=thd->real_id; @@ -3267,6 +3283,7 @@ void Item_func_benchmark::print(String *str) str->append(')'); } + /* This function is just used to create tests with time gaps */ longlong Item_func_sleep::val_int() @@ -3287,10 +3304,14 @@ longlong Item_func_sleep::val_int() thd->mysys_var->current_mutex= &LOCK_user_locks; thd->mysys_var->current_cond= &cond; - while (!thd->killed && - (error= pthread_cond_timedwait(&cond, &LOCK_user_locks, - &abstime)) != ETIMEDOUT && - error != EINVAL) ; + error= 0; + while (!thd->killed) + { + error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime); + if (error == ETIMEDOUT || error == ETIME) + break; + error= 0; + } pthread_mutex_lock(&thd->mysys_var->mutex); thd->mysys_var->current_mutex= 0; @@ -3300,7 +3321,7 @@ longlong Item_func_sleep::val_int() pthread_mutex_unlock(&LOCK_user_locks); pthread_cond_destroy(&cond); - return (error == ETIMEDOUT) ? 0 : 1; + return test(!error); // Return 1 killed } @@ -4729,10 +4750,7 @@ Item_func_sp::execute(Item **itp) ER_FAILED_ROUTINE_BREAK_BINLOG, ER(ER_FAILED_ROUTINE_BREAK_BINLOG)); -#ifndef NO_EMBEDDED_ACCESS_CHECKS sp_restore_security_context(thd, save_ctx); -#endif - error: DBUG_RETURN(res); } @@ -4846,11 +4864,12 @@ Item_func_sp::tmp_table_field(TABLE *t_arg) find_and_check_access() thd thread handler want_access requested access - backup backup of security context or 0 + save backup of security context RETURN FALSE Access granted TRUE Requested access can't be granted or function doesn't exists + In this case security context is not changed and *save = 0 NOTES Checks if requested access to function can be granted to user. @@ -4865,12 +4884,11 @@ Item_func_sp::tmp_table_field(TABLE *t_arg) bool Item_func_sp::find_and_check_access(THD *thd, ulong want_access, - Security_context **backup) + Security_context **save) { - bool res; - Security_context *local_save, - **save= (backup ? backup : &local_save); - res= TRUE; + bool res= TRUE; + + *save= 0; // Safety if error if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE))) { my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); @@ -4880,26 +4898,31 @@ Item_func_sp::find_and_check_access(THD *thd, ulong want_access, #ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_routine_access(thd, want_access, m_sp->m_db.str, m_sp->m_name.str, 0, FALSE)) - { goto error; - } sp_change_security_context(thd, m_sp, save); + /* + If we changed context to run as another user, we need to check the + access right for the new context again as someone may have deleted + this person the right to use the procedure + + TODO: + Cache if the definer has the right to use the object on the first + usage and only reset the cache if someone does a GRANT statement + that 'may' affect this. + */ if (*save && check_routine_access(thd, want_access, m_sp->m_db.str, m_sp->m_name.str, 0, FALSE)) { - goto error_check_ctx; + sp_restore_security_context(thd, *save); + *save= 0; // Safety + goto error; } - res= FALSE; -error_check_ctx: - if (*save && (res || !backup)) - sp_restore_security_context(thd, local_save); -error: -#else - res= 0; -error: #endif + res= FALSE; // no error + +error: return res; } @@ -4909,7 +4932,11 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) bool res; DBUG_ASSERT(fixed == 0); res= Item_func::fix_fields(thd, ref); - if (!res && find_and_check_access(thd, EXECUTE_ACL, NULL)) - res= 1; + if (!res) + { + Security_context *save_ctx; + if (!(res= find_and_check_access(thd, EXECUTE_ACL, &save_ctx))) + sp_restore_security_context(thd, save_ctx); + } return res; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 018afac3812..1812256d532 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1964,21 +1964,16 @@ String *Item_func_char::val_str(String *str) int32 num=(int32) args[i]->val_int(); if (!args[i]->null_value) { -#ifdef USE_MB - if (use_mb(collation.collation)) - { - if (num&0xFF000000L) { - str->append((char)(num>>24)); - goto b2; - } else if (num&0xFF0000L) { -b2: str->append((char)(num>>16)); - goto b1; - } else if (num&0xFF00L) { -b1: str->append((char)(num>>8)); - } + if (num&0xFF000000L) { + str->append((char)(num>>24)); + goto b2; + } else if (num&0xFF0000L) { + b2: str->append((char)(num>>16)); + goto b1; + } else if (num&0xFF00L) { + b1: str->append((char)(num>>8)); } -#endif - str->append((char)num); + str->append((char) num); } } str->set_charset(collation.collation); @@ -1997,7 +1992,7 @@ b1: str->append((char)(num>>8)); enum MYSQL_ERROR::enum_warning_level level; uint diff= str->length() - wlen; set_if_smaller(diff, 3); - octet2hex(hexbuf, (const uchar*) str->ptr() + wlen, diff); + octet2hex(hexbuf, str->ptr() + wlen, diff); if (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)) { @@ -2436,6 +2431,7 @@ String *Item_func_collation::val_str(String *str) String *Item_func_hex::val_str(String *str) { + String *res; DBUG_ASSERT(fixed == 1); if (args[0]->result_type() != STRING_RESULT) { @@ -2464,24 +2460,16 @@ String *Item_func_hex::val_str(String *str) } /* Convert given string to a hex string, character by character */ - String *res= args[0]->val_str(str); - const char *from, *end; - char *to; - if (!res || tmp_value.alloc(res->length()*2)) + res= args[0]->val_str(str); + if (!res || tmp_value.alloc(res->length()*2+1)) { null_value=1; return 0; } null_value=0; tmp_value.length(res->length()*2); - for (from=res->ptr(), end=from+res->length(), to= (char*) tmp_value.ptr(); - from < end ; - from++, to+=2) - { - uint tmp=(uint) (uchar) *from; - to[0]=_dig_vec_upper[tmp >> 4]; - to[1]=_dig_vec_upper[tmp & 15]; - } + + octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length()); return &tmp_value; } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index fa098849a43..ec470bb242b 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -484,7 +484,7 @@ public: String *val_str(String *); void fix_length_and_dec() { - collation.set(default_charset()); + collation.set(&my_charset_bin); maybe_null=0; max_length=arg_count; } const char *func_name() const { return "char"; } diff --git a/sql/log_event.cc b/sql/log_event.cc index 55c761d4c6e..ed6599f692f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -212,24 +212,18 @@ static inline int read_str(char **buf, char *buf_end, char **str, /* Transforms a string into "" or its expression in 0x... form. */ + char *str_to_hex(char *to, const char *from, uint len) { - char *p= to; if (len) { - p= strmov(p, "0x"); - for (uint i= 0; i < len; i++, p+= 2) - { - /* val[i] is char. Casting to uchar helps greatly if val[i] < 0 */ - uint tmp= (uint) (uchar) from[i]; - p[0]= _dig_vec_upper[tmp >> 4]; - p[1]= _dig_vec_upper[tmp & 15]; - } - *p= 0; + *to++= '0'; + *to++= 'x'; + to= octet2hex(to, from, len); } else - p= strmov(p, "\"\""); - return p; // pointer to end 0 of 'to' + to= strmov(to, "\"\""); + return to; // pointer to end 0 of 'to' } /* diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 5c7053e6e2a..d3e5645bafc 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -372,8 +372,10 @@ my_bool rename_in_schema_file(const char *schema, const char *old_name, if (revision > 0 && !access(arc_path, F_OK)) { - ulonglong limit= (revision > num_view_backups) ? revision - num_view_backups : 0; - while (revision > limit) { + ulonglong limit= ((revision > num_view_backups) ? + revision - num_view_backups : 0); + for (; revision > limit ; revision--) + { my_snprintf(old_path, FN_REFLEN, "%s/%s%s-%04lu", arc_path, old_name, reg_ext, (ulong)revision); (void) unpack_filename(old_path, old_path); @@ -381,7 +383,6 @@ my_bool rename_in_schema_file(const char *schema, const char *old_name, arc_path, new_name, reg_ext, (ulong)revision); (void) unpack_filename(new_path, new_path); my_rename(old_path, new_path, MYF(0)); - revision--; } } return 0; diff --git a/sql/password.c b/sql/password.c index aa05be8c740..562df3ae226 100644 --- a/sql/password.c +++ b/sql/password.c @@ -316,18 +316,21 @@ void create_random_string(char *to, uint length, struct rand_struct *rand_st) octet2hex() buf OUT output buffer. Must be at least 2*len+1 bytes str, len IN the beginning and the length of the input string + + RETURN + buf+len*2 */ -void -octet2hex(char *to, const unsigned char *str, uint len) +char *octet2hex(char *to, const char *str, uint len) { - const uint8 *str_end= str + len; + const byte *str_end= str + len; for (; str != str_end; ++str) { - *to++= _dig_vec_upper[(*str & 0xF0) >> 4]; - *to++= _dig_vec_upper[*str & 0x0F]; + *to++= _dig_vec_upper[((uchar) *str) >> 4]; + *to++= _dig_vec_upper[((uchar) *str) & 0x0F]; } *to= '\0'; + return to; } diff --git a/sql/slave.cc b/sql/slave.cc index b1763187d04..cc7ec5e5ae8 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2747,7 +2747,7 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, else pthread_cond_wait(&data_cond, &data_lock); DBUG_PRINT("info",("Got signal of master update or timed out")); - if (error == ETIMEDOUT) + if (error == ETIMEDOUT || error == ETIME) { error= -1; break; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 51b9fe43796..35187047364 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2784,7 +2784,6 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, Natural_join_column *nj_col; Field *found_field; Query_arena *arena, backup; - DBUG_ENTER("find_field_in_natural_join"); DBUG_PRINT("enter", ("field name: '%s', ref 0x%lx", name, (ulong) ref)); @@ -2809,6 +2808,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, if (nj_col->view_field) { + Item *item; /* The found field is a view field, we do as in find_field_in_view() and return a pointer to pointer to the Item of that field. @@ -2816,7 +2816,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, if (register_tree_change) arena= thd->activate_stmt_arena_if_needed(&backup); - Item *item= nj_col->create_item(thd); + item= nj_col->create_item(thd); if (register_tree_change && arena) thd->restore_active_arena(arena, &backup); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index cc4b291b5d1..fbfce2e3a31 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1809,7 +1809,7 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg) #endif if (thd->killed || di->status) break; - if (error == ETIMEDOUT) + if (error == ETIMEDOUT || error == ETIME) { thd->killed= THD::KILL_CONNECTION; break; diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index 0af6a80d4c2..54599314293 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -58,12 +58,14 @@ extern "C" pthread_handler_decl(handle_manager,arg __attribute__((unused))) set_timespec(abstime, flush_time); reset_flush_time = FALSE; } - while (!manager_status && !error && !abort_loop) - error = pthread_cond_timedwait(&COND_manager, &LOCK_manager, &abstime); + while (!manager_status && (!error || error == EINTR) && !abort_loop) + error= pthread_cond_timedwait(&COND_manager, &LOCK_manager, &abstime); } else - while (!manager_status && !error && !abort_loop) - error = pthread_cond_wait(&COND_manager, &LOCK_manager); + { + while (!manager_status && (!error || error == EINTR) && !abort_loop) + error= pthread_cond_wait(&COND_manager, &LOCK_manager); + } status = manager_status; manager_status = 0; pthread_mutex_unlock(&LOCK_manager); @@ -71,7 +73,7 @@ extern "C" pthread_handler_decl(handle_manager,arg __attribute__((unused))) if (abort_loop) break; - if (error) /* == ETIMEDOUT */ + if (error == ETIMEDOUT || error == ETIME) { flush_tables(); error = 0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8a6b776e803..e28eff4f577 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5054,11 +5054,16 @@ check_routine_access(THD *thd, ulong want_access,char *db, char *name, tables->db= db; tables->table_name= tables->alias= name; - if ((thd->security_ctx->master_access & want_access) == want_access && - !thd->db) + /* + The following test is just a shortcut for check_access() (to avoid + calculating db_access) under the assumption that it's common to + give persons global right to execute all stored SP (but not + necessary to create them). + */ + if ((thd->security_ctx->master_access & want_access) == want_access) tables->grant.privilege= want_access; else if (check_access(thd,want_access,db,&tables->grant.privilege, - 0, no_errors, test(tables->schema_table))) + 0, no_errors, 0)) return TRUE; #ifndef NO_EMBEDDED_ACCESS_CHECKS diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index aebe7880451..5f3539ca1e9 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2887,7 +2887,7 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) thd->protocol= &thd->protocol_simple; /* use normal protocol */ /* Assert that if an error, no cursor is open */ - DBUG_ASSERT(! (rc && cursor)); + DBUG_ASSERT(! (error && cursor)); if (! cursor) { diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1b1a35d2584..f38ef19614e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2474,11 +2474,11 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond, and use them in equality propagation process (see details in OptimizerKBAndTodo) */ - if ((cond->functype() == Item_func::BETWEEN) && - value[0]->eq(value[1], field->binary())) - eq_func= TRUE; - else + if ((cond->functype() != Item_func::BETWEEN) || + ((Item_func_between*) cond)->negated || + !value[0]->eq(value[1], field->binary())) return; + eq_func= TRUE; } if (field->result_type() == STRING_RESULT) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2d98e834de7..1eb8aa1acb9 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1258,9 +1258,6 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) VOID(pthread_mutex_unlock(&LOCK_thread_count)); thread_info *thd_info; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - Security_context *sctx; -#endif time_t now= time(0); while ((thd_info=thread_infos.get())) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8fb39ea3098..9c3ea710dfc 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3156,15 +3156,14 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (create_info->row_type == ROW_TYPE_NOT_USED) create_info->row_type= table->s->row_type; - DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type)); - if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) - || ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED)) + DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type)); + if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) || + ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED)) { DBUG_PRINT("info", ("doesn't support alter")); my_error(ER_ILLEGAL_HA, MYF(0), table_name); DBUG_RETURN(TRUE); } - DBUG_PRINT("info", ("supports alter")); thd->proc_info="setup"; if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) && diff --git a/sql/sql_view.cc b/sql/sql_view.cc index f956d9d4928..5db08275735 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1427,7 +1427,7 @@ mysql_rename_view(THD *thd, /* get view definition and source */ if (parser->parse((gptr)&view_def, thd->mem_root, view_parameters, - sizeof(view_parameters)/sizeof(view_parameters[0])-1)) + array_elements(view_parameters)-1)) goto err; /* rename view and it's backups */ diff --git a/sql/unireg.cc b/sql/unireg.cc index d297b143d3b..7c244b20a8b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -474,16 +474,10 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, char *dst; uint length= field->interval->type_lengths[pos], hex_length; const char *src= field->interval->type_names[pos]; - const char *srcend= src + length; hex_length= length * 2; field->interval->type_lengths[pos]= hex_length; field->interval->type_names[pos]= dst= sql_alloc(hex_length + 1); - for ( ; src < srcend; src++) - { - *dst++= _dig_vec_upper[((uchar) *src) >> 4]; - *dst++= _dig_vec_upper[((uchar) *src) & 15]; - } - *dst= '\0'; + octet2hex(dst, src, length); } } From 4b2a0f0c70e31ab7796d0adb84127ad073ed26af Mon Sep 17 00:00:00 2001 From: "gluh@eagle.intranet.mysql.r18.ru" <> Date: Wed, 12 Oct 2005 13:18:46 +0500 Subject: [PATCH 12/13] after merge fix --- config/ac-macros/yassl.m4 | 2 +- sql/mysqld.cc | 34 ++++++++++++++------------- sql/sql_parse.cc | 48 +++++++++++++++++++-------------------- 3 files changed, 43 insertions(+), 41 deletions(-) diff --git a/config/ac-macros/yassl.m4 b/config/ac-macros/yassl.m4 index 972e4530dab..dcd72cb14f1 100644 --- a/config/ac-macros/yassl.m4 +++ b/config/ac-macros/yassl.m4 @@ -20,7 +20,7 @@ AC_DEFUN([MYSQL_CHECK_YASSL], [ -L\$(top_builddir)/extra/yassl/taocrypt/src -ltaocrypt" openssl_includes="-I\$(top_srcdir)/extra/yassl/include" AC_DEFINE([HAVE_OPENSSL], [1], [Defined by configure. Using yaSSL for OpenSSL emulation.]) - + AC_DEFINE([HAVE_YASSL], [1], [Defined by configure. Using yaSSL for OpenSSL emulation.]) # System specific checks yassl_integer_extra_cxxflags="" case $host_cpu--$CXX_VERSION in diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ed7c52cb859..5befcd6d503 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -580,21 +580,21 @@ HANDLE smem_event_connect_request= 0; #include "sslopt-vars.h" #ifdef HAVE_OPENSSL #include - +#ifndef HAVE_YASSL typedef struct CRYPTO_dynlock_value { rw_lock_t lock; } openssl_lock_t; -char *des_key_file; -struct st_VioSSLAcceptorFd *ssl_acceptor_fd; static openssl_lock_t *openssl_stdlocks; - static openssl_lock_t *openssl_dynlock_create(const char *, int); static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int); static void openssl_lock_function(int, int, const char *, int); static void openssl_lock(int, openssl_lock_t *, const char *, int); static unsigned long openssl_id_function(); +#endif +char *des_key_file; +struct st_VioSSLAcceptorFd *ssl_acceptor_fd; #endif /* HAVE_OPENSSL */ @@ -1184,10 +1184,12 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_user_conn); #ifdef HAVE_OPENSSL (void) pthread_mutex_destroy(&LOCK_des_key_file); +#ifndef HAVE_YASSL for (int i= 0; i < CRYPTO_num_locks(); ++i) (void) rwlock_destroy(&openssl_stdlocks[i].lock); OPENSSL_free(openssl_stdlocks); #endif +#endif #ifdef HAVE_REPLICATION (void) pthread_mutex_destroy(&LOCK_rpl_status); (void) pthread_cond_destroy(&COND_rpl_status); @@ -2743,6 +2745,17 @@ static int init_thread_environment() (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST); #ifdef HAVE_OPENSSL (void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST); +#ifndef HAVE_YASSL + openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() * + sizeof(openssl_lock_t)); + for (int i= 0; i < CRYPTO_num_locks(); ++i) + (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL); + CRYPTO_set_dynlock_create_callback(openssl_dynlock_create); + CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy); + CRYPTO_set_dynlock_lock_callback(openssl_lock); + CRYPTO_set_locking_callback(openssl_lock_function); + CRYPTO_set_id_callback(openssl_id_function); +#endif #endif (void) my_rwlock_init(&LOCK_sys_init_connect, NULL); (void) my_rwlock_init(&LOCK_sys_init_slave, NULL); @@ -2771,22 +2784,11 @@ static int init_thread_environment() sql_print_error("Can't create thread-keys"); return 1; } -#ifdef HAVE_OPENSSL - openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() * - sizeof(openssl_lock_t)); - for (int i= 0; i < CRYPTO_num_locks(); ++i) - (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL); - CRYPTO_set_dynlock_create_callback(openssl_dynlock_create); - CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy); - CRYPTO_set_dynlock_lock_callback(openssl_lock); - CRYPTO_set_locking_callback(openssl_lock_function); - CRYPTO_set_id_callback(openssl_id_function); -#endif return 0; } -#ifdef HAVE_OPENSSL +#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) static unsigned long openssl_id_function() { return (unsigned long) pthread_self(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 96b9dd84011..b6f23e635c0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3194,36 +3194,36 @@ end_with_restore_list: if (result != 2) break; case SQLCOM_UPDATE_MULTI: + { + DBUG_ASSERT(first_table == all_tables && first_table != 0); + /* if we switched from normal update, rights are checked */ + if (result != 2) { - DBUG_ASSERT(first_table == all_tables && first_table != 0); - /* if we switched from normal update, rights are checked */ - if (result != 2) - { - if ((res= multi_update_precheck(thd, all_tables))) - break; - } - else - res= 0; + if ((res= multi_update_precheck(thd, all_tables))) + break; + } + else + res= 0; - if ((res= mysql_multi_update_prepare(thd))) - break; + if ((res= mysql_multi_update_prepare(thd))) + break; #ifdef HAVE_REPLICATION - /* Check slave filtering rules */ - if (thd->slave_thread && all_tables_not_ok(thd, all_tables)) - { - /* we warn the slave SQL thread */ - my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); - break; - } + /* Check slave filtering rules */ + if (thd->slave_thread && all_tables_not_ok(thd, all_tables)) + { + /* we warn the slave SQL thread */ + my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); + break; + } #endif /* HAVE_REPLICATION */ - res= mysql_multi_update(thd, all_tables, - &select_lex->item_list, - &lex->value_list, - select_lex->where, - select_lex->options, - lex->duplicates, lex->ignore, unit, select_lex); + res= mysql_multi_update(thd, all_tables, + &select_lex->item_list, + &lex->value_list, + select_lex->where, + select_lex->options, + lex->duplicates, lex->ignore, unit, select_lex); break; } case SQLCOM_REPLACE: From 6266243deb54299c0bc19516aeb239e59218d704 Mon Sep 17 00:00:00 2001 From: "sergefp@mysql.com" <> Date: Wed, 12 Oct 2005 16:43:55 +0400 Subject: [PATCH 13/13] Fix compile error on Windows: remove wrong typecast --- sql/ha_innodb.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index cbd23aaab6c..455b54361f0 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -7042,8 +7042,7 @@ ha_innobase::cmp_ref( (const char*)ref1, len1, (const char*)ref2, len2); } else { - result = field->key_cmp((const char*)ref1, - (const char*)ref2); + result = field->key_cmp(ref1, ref2); } if (result) {