From ba0697c6584d20f730148ec8c5171c2aca48086f Mon Sep 17 00:00:00 2001 From: "ingo@mysql.com" <> Date: Thu, 6 May 2004 16:15:46 +0200 Subject: [PATCH 01/47] Fix a forgotten skip of space at line begin for the 'system' command. --- BitKeeper/etc/logging_ok | 1 + client/mysql.cc | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index b805749821c..a51078f675f 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -39,6 +39,7 @@ hf@deer.mysql.r18.ru hf@genie.(none) igor@hundin.mysql.fi igor@rurik.mysql.com +ingo@mysql.com jani@dsl-jkl1657.dial.inet.fi jani@hynda.(none) jani@hynda.mysql.fi diff --git a/client/mysql.cc b/client/mysql.cc index 695cb1f28be..46ade3aef26 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2042,6 +2042,10 @@ static int com_shell(String *buffer, char *line __attribute__((unused))) { char *shell_cmd; + + /* Skip space from line begin */ + while (isspace(*line)) + line++; if (!(shell_cmd = strchr(line, ' '))) { put_info("Usage: \\! shell-command", INFO_ERROR); From 7d575447edcf65db4515dd4c17598c26462e2920 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Thu, 6 May 2004 22:55:30 +0200 Subject: [PATCH 02/47] A DBUG_RETURN to match a DBUG_ENTER --- myisam/mi_dynrec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/myisam/mi_dynrec.c b/myisam/mi_dynrec.c index 2a3f4aec0a8..0ffab05b6bc 100644 --- a/myisam/mi_dynrec.c +++ b/myisam/mi_dynrec.c @@ -311,7 +311,7 @@ static int update_backward_delete_link(MI_INFO *info, my_off_t delete_block, DBUG_RETURN(1); /* Wrong delete link */ } } - return 0; + DBUG_RETURN(0); } /* Delete datarecord from database */ From 6bc03b14d9198a83a8dc668330f053240d1d98f4 Mon Sep 17 00:00:00 2001 From: "jani@a80-186-24-72.elisa-laajakaista.fi" <> Date: Fri, 7 May 2004 01:02:57 +0300 Subject: [PATCH 03/47] Fixed a problem with option --where, which earlier was not dynamic. One was not able to use long query strings with it. Bug#3633 --- BitKeeper/etc/logging_ok | 1 + client/mysqldump.c | 63 ++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index b805749821c..ef879971e38 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -39,6 +39,7 @@ hf@deer.mysql.r18.ru hf@genie.(none) igor@hundin.mysql.fi igor@rurik.mysql.com +jani@a80-186-24-72.elisa-laajakaista.fi jani@dsl-jkl1657.dial.inet.fi jani@hynda.(none) jani@hynda.mysql.fi diff --git a/client/mysqldump.c b/client/mysqldump.c index 42b094d2902..f264b9b61c6 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -36,7 +36,7 @@ ** Added --single-transaction option 06/06/2002 by Peter Zaitsev */ -#define DUMP_VERSION "9.10" +#define DUMP_VERSION "9.11" #include #include @@ -938,18 +938,32 @@ static char *field_escape(char *to,const char *from,uint length) } /* field_escape */ +static char *alloc_query_str(ulong size) +{ + char *query; + + if (!(query= (char*) my_malloc(size, MYF(MY_WME)))) + { + ignore_errors= 0; /* Fatal error */ + safe_exit(EX_MYSQLERR); /* Force exit */ + } + return query; +} + /* ** dumpTable saves database contents as a series of INSERT statements. */ static void dumpTable(uint numFields, char *table) { - char query[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3]; + char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3]; char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table; + char *query= query_buf; MYSQL_RES *res; MYSQL_FIELD *field; MYSQL_ROW row; ulong rownr, row_break, total_length, init_length; const char *table_type; + int error= 0; result_table= quote_name(table,table_buff, 1); opt_quoted_table= quote_name(table, table_buff2, 0); @@ -995,8 +1009,11 @@ static void dumpTable(uint numFields, char *table) sprintf(buff," FROM %s", result_table); end= strmov(end,buff); if (where) - end= strxmov(end, " WHERE ",where,NullS); - if (mysql_query(sock, query)) + { + query= alloc_query_str((ulong) (strlen(where) + (end - query) + 10)); + end= strxmov(query, query_buf, " WHERE ", where, NullS); + } + if (mysql_real_query(sock, query, (uint) (end - query))) { DBerror(sock, "when executing 'SELECT INTO OUTFILE'"); return; @@ -1013,14 +1030,16 @@ static void dumpTable(uint numFields, char *table) { if (!opt_xml && opt_comments) fprintf(md_result_file,"-- WHERE: %s\n",where); - strxmov(strend(query), " WHERE ",where,NullS); + query= alloc_query_str((ulong) (strlen(where) + strlen(query) + 10)); + strxmov(query, query_buf, " WHERE ", where, NullS); } if (!opt_xml) fputs("\n", md_result_file); if (mysql_query(sock, query)) { DBerror(sock, "when retrieving data from server"); - return; + error= EX_CONSCHECK; + goto err; } if (quick) res=mysql_use_result(sock); @@ -1029,7 +1048,8 @@ static void dumpTable(uint numFields, char *table) if (!res) { DBerror(sock, "when retrieving data from server"); - return; + error= EX_CONSCHECK; + goto err; } if (verbose) fprintf(stderr, "-- Retrieving rows...\n"); @@ -1037,8 +1057,8 @@ static void dumpTable(uint numFields, char *table) { fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n", my_progname, result_table); - safe_exit(EX_CONSCHECK); - return; + error= EX_CONSCHECK; + goto err; } if (opt_disable_keys) @@ -1076,8 +1096,8 @@ static void dumpTable(uint numFields, char *table) sprintf(query,"%s: Not enough fields from table %s! Aborting.\n", my_progname, result_table); fputs(query,stderr); - safe_exit(EX_CONSCHECK); - return; + error= EX_CONSCHECK; + goto err; } if (extended_insert) { @@ -1096,7 +1116,8 @@ static void dumpTable(uint numFields, char *table) if (dynstr_realloc(&extended_row,length * 2+2)) { fputs("Aborting dump (out of memory)",stderr); - safe_exit(EX_EOM); + error= EX_EOM; + goto err; } dynstr_append(&extended_row,"\'"); extended_row.length += @@ -1131,7 +1152,8 @@ static void dumpTable(uint numFields, char *table) else if (dynstr_append(&extended_row,"NULL")) { fputs("Aborting dump (out of memory)",stderr); - safe_exit(EX_EOM); + error= EX_EOM; + goto err; } } else @@ -1229,8 +1251,8 @@ static void dumpTable(uint numFields, char *table) result_table, rownr); fputs(query,stderr); - safe_exit(EX_CONSCHECK); - return; + error= EX_CONSCHECK; + goto err; } if (opt_lock) fputs("UNLOCK TABLES;\n", md_result_file); @@ -1240,7 +1262,16 @@ static void dumpTable(uint numFields, char *table) if (opt_autocommit) fprintf(md_result_file, "commit;\n"); mysql_free_result(res); - } + if (query != query_buf) + my_free(query, MYF(MY_ALLOW_ZERO_PTR)); + } + return; + +err: + if (query != query_buf) + my_free(query, MYF(MY_ALLOW_ZERO_PTR)); + safe_exit(error); + return; } /* dumpTable */ From c066b3022e9ce6606f6ccc214bbdc3b85a83dfcb Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Fri, 7 May 2004 12:13:45 +0300 Subject: [PATCH 04/47] Fix auto_inc locking bug introduced in ChangeSet@1.1794.1.1 --- innobase/row/row0mysql.c | 2 +- mysql-test/r/innodb.result | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index f53a8de2080..bdc47ca0e8e 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -696,7 +696,7 @@ run_again: trx_start_if_not_started(trx); - err = lock_table(0, prebuilt->table, prebuilt->select_lock_type, thr); + err = lock_table(0, prebuilt->table, LOCK_AUTO_INC, thr); trx->error_state = err; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 1a92946bfcd..6a67bbc6f8b 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -431,7 +431,7 @@ Duplicate entry 'test2' for key 2 select * from t1; id ggid email passwd 1 this will work -4 test2 this will work +3 test2 this will work select * from t1 where id=1; id ggid email passwd 1 this will work From 309c7412f6a7b2c84a576a0d49695a6b8b0b9b30 Mon Sep 17 00:00:00 2001 From: "ingo@mysql.com" <> Date: Mon, 10 May 2004 12:15:40 +0200 Subject: [PATCH 05/47] Fix replace_result of $MASTER_MYPORT instead of literal numbers. --- mysql-test/t/rpl000015.test | 2 +- mysql-test/t/rpl_error_ignored_table.test | 2 +- mysql-test/t/rpl_log.test | 6 +++--- mysql-test/t/rpl_log_pos.test | 8 ++++---- mysql-test/t/rpl_max_relay_size.test | 12 ++++++------ mysql-test/t/rpl_rotate_logs.test | 10 +++++----- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test index 26d32ea3e11..7c5a8bf3743 100644 --- a/mysql-test/t/rpl000015.test +++ b/mysql-test/t/rpl000015.test @@ -11,7 +11,7 @@ show slave status; change master to master_host='127.0.0.1'; # The following needs to be cleaned up when change master is fixed ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT show slave status; --replace_result $MASTER_MYPORT MASTER_PORT eval change master to master_host='127.0.0.1',master_user='root', diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test index 4f15f9de0a2..a0b0f1fd599 100644 --- a/mysql-test/t/rpl_error_ignored_table.test +++ b/mysql-test/t/rpl_error_ignored_table.test @@ -14,7 +14,7 @@ connection slave; sync_with_master; # The port number is different when doing the release build with # Do-compile, hence we have to replace the port number here accordingly ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; # check that the table has been ignored, because otherwise the test is nonsense show tables like 't1'; diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test index e01b3e4e09c..df2b9ecd0cb 100644 --- a/mysql-test/t/rpl_log.test +++ b/mysql-test/t/rpl_log.test @@ -79,11 +79,11 @@ connection slave; slave start; sync_with_master; show master logs; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION +--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION show binlog events in 'slave-bin.001' from 4; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION +--replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION show binlog events in 'slave-bin.002' from 4; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; # Need to recode the following diff --git a/mysql-test/t/rpl_log_pos.test b/mysql-test/t/rpl_log_pos.test index 859180d4e25..1a9a5bc3448 100644 --- a/mysql-test/t/rpl_log_pos.test +++ b/mysql-test/t/rpl_log_pos.test @@ -6,7 +6,7 @@ show master status; save_master_pos; connection slave; sync_with_master; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; slave stop; change master to master_log_pos=73; @@ -15,17 +15,17 @@ sleep 5; slave stop; change master to master_log_pos=73; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; slave start; sleep 5; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; slave stop; change master to master_log_pos=173; slave start; sleep 2; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; connection master; show master status; diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test index 7e9a8a1872e..d2278b6d6df 100644 --- a/mysql-test/t/rpl_max_relay_size.test +++ b/mysql-test/t/rpl_max_relay_size.test @@ -28,7 +28,7 @@ set global max_relay_log_size=8192-1; # mapped to 4096 select @@global.max_relay_log_size; start slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; stop slave; reset slave; @@ -36,7 +36,7 @@ set global max_relay_log_size=(5*4096); select @@global.max_relay_log_size; start slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 18 # show slave status; stop slave; @@ -45,7 +45,7 @@ set global max_relay_log_size=0; select @@global.max_relay_log_size; start slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; # Tests below are mainly to ensure that we have not coded with wrong assumptions @@ -55,7 +55,7 @@ reset slave; # test of relay log rotation when the slave is stopped # (to make sure it does not crash). flush logs; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; reset slave; @@ -70,7 +70,7 @@ create table t1 (a int); save_master_pos; connection slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; # one more rotation, to be sure Relay_log_space is correctly updated flush logs; @@ -79,7 +79,7 @@ drop table t1; save_master_pos; connection slave; sync_with_master; ---replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; connection master; diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index 70366fc1749..76a06d01fa9 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -25,13 +25,13 @@ system chmod 600 var/slave-data/master.info; # init_strvar_from_file() in init_master_info()). --error 1201 slave start; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT # CHANGE MASTER will fail because it first parses master.info before changing it # (so when master.info is bad, people have to use RESET SLAVE first). --error 1201 eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; reset slave; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; connection master; reset master; @@ -49,7 +49,7 @@ insert into t1 values('Could not break slave'),('Tried hard'); save_master_pos; connection slave; sync_with_master; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 18 # show slave status; select * from t1; @@ -101,7 +101,7 @@ insert into t2 values (65); save_master_pos; connection slave; sync_with_master; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 18 # show slave status; select * from t2; @@ -133,7 +133,7 @@ connection slave; sync_with_master; select * from t4; ---replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT +--replace_result $MASTER_MYPORT MASTER_PORT --replace_column 18 # show slave status; # because of concurrent insert, the table may not be up to date From 2cbc4e71fcec35820a85998e602fccb8ad1609a2 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 10 May 2004 12:39:01 +0200 Subject: [PATCH 06/47] backport from 4.1: "phrase search" should not match partial words (it should not match 'paraphrase searches') --- myisam/ft_boolean_search.c | 29 +++++++++++++++++++---------- myisam/ft_parser.c | 9 --------- myisam/ftdefs.h | 5 +++-- mysql-test/r/fulltext.result | 3 ++- mysql-test/t/fulltext.test | 1 + 5 files changed, 25 insertions(+), 22 deletions(-) diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index d728c379ea5..61381f80783 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -360,25 +360,34 @@ err: } -/* returns 1 if str0 contain str1 */ +/* returns 1 if str0 ~= /\/ */ static int _ftb_strstr(const byte *s0, const byte *e0, const byte *s1, const byte *e1, CHARSET_INFO *cs) { - const byte *p; + const byte *p0, *p1; + my_bool s_after, e_before; - while (s0 < e0) + s_after=true_word_char(s1[0]); + e_before=true_word_char(e1[-1]); + p0=s0; + + while (p0 < e0) { - while (s0 < e0 && cs->to_upper[(uint) (uchar) *s0++] != + while (p0 < e0 && cs->to_upper[(uint) (uchar) *p0++] != cs->to_upper[(uint) (uchar) *s1]) /* no-op */; - if (s0 >= e0) + if (p0 >= e0) return 0; - p=s1+1; - while (s0 < e0 && p < e1 && cs->to_upper[(uint) (uchar) *s0] == - cs->to_upper[(uint) (uchar) *p]) - s0++, p++; - if (p >= e1) + + if (s_after && p0-1 > s0 && true_word_char(p0[-2])) + continue; + + p1=s1+1; + while (p0 < e0 && p1 < e1 && cs->to_upper[(uint) (uchar) *p0] == + cs->to_upper[(uint) (uchar) *p1]) + p0++, p1++; + if (p1 == e1 && (!e_before || p0 == e0 || !true_word_char(p0[0]))) return 1; } return 0; diff --git a/myisam/ft_parser.c b/myisam/ft_parser.c index c25ed6022a0..f397660af6b 100644 --- a/myisam/ft_parser.c +++ b/myisam/ft_parser.c @@ -105,15 +105,6 @@ FT_WORD * ft_linearize(TREE *wtree) DBUG_RETURN(wlist); } -#define true_word_char(X) (isalnum(X) || (X)=='_') -#ifdef HYPHEN_IS_DELIM -#define misc_word_char(X) ((X)=='\'') -#else -#define misc_word_char(X) ((X)=='\'' || (X)=='-') -#endif -#define word_char(X) (true_word_char(X) || misc_word_char(X)) - - /* returns: * 0 - eof * 1 - word found diff --git a/myisam/ftdefs.h b/myisam/ftdefs.h index 62fa4362e19..46acf60d796 100644 --- a/myisam/ftdefs.h +++ b/myisam/ftdefs.h @@ -22,8 +22,9 @@ #include #include -#define HYPHEN_IS_DELIM -#define HYPHEN_IS_CONCAT /* not used for now */ +#define true_word_char(X) (isalnum(X) || (X)=='_') +#define misc_word_char(X) ((X)=='\'') +#define word_char(X) (true_word_char(X) || misc_word_char(X)) #define COMPILE_STOPWORDS_IN diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 738941f63c7..baa3a834f6f 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -116,7 +116,8 @@ a b MySQL has now support for full-text search select * from t1 where MATCH a,b AGAINST ('"text i"' IN BOOLEAN MODE); a b -Full-text indexes are called collections +select * from t1 where MATCH a,b AGAINST ('"xt indexes"' IN BOOLEAN MODE); +a b select * from t1 where MATCH a,b AGAINST ('+(support collections) +foobar*' IN BOOLEAN MODE); a b select * from t1 where MATCH a,b AGAINST ('+(+(support collections)) +foobar*' IN BOOLEAN MODE); diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 774a3b42619..86d2cde370a 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -52,6 +52,7 @@ select * from t1 where MATCH a,b AGAINST ('"text search" "now support"' IN BOOL select * from t1 where MATCH a,b AGAINST ('"text search" -"now support"' IN BOOLEAN MODE); select * from t1 where MATCH a,b AGAINST ('"text search" +"now support"' IN BOOLEAN MODE); select * from t1 where MATCH a,b AGAINST ('"text i"' IN BOOLEAN MODE); +select * from t1 where MATCH a,b AGAINST ('"xt indexes"' IN BOOLEAN MODE); select * from t1 where MATCH a,b AGAINST ('+(support collections) +foobar*' IN BOOLEAN MODE); select * from t1 where MATCH a,b AGAINST ('+(+(support collections)) +foobar*' IN BOOLEAN MODE); From d48d5681c8733a1f6d75eb13f51654513e93a097 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Mon, 10 May 2004 17:15:29 +0300 Subject: [PATCH 07/47] InnoDB: Fix assertion failure for orphaned tables in DROP DATABASE --- innobase/row/row0mysql.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index bdc47ca0e8e..228f19c865f 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2208,10 +2208,11 @@ row_drop_database_for_mysql( dict_table_t* table; char* table_name; int err = DB_SUCCESS; + ulint namelen = strlen(name); ut_ad(trx->mysql_thread_id == os_thread_get_curr_id()); ut_a(name != NULL); - ut_a(name[strlen(name) - 1] == '/'); + ut_a(name[namelen - 1] == '/'); trx->op_info = (char *) "dropping database"; @@ -2220,7 +2221,7 @@ loop: row_mysql_lock_data_dictionary(trx); while ((table_name = dict_get_first_table_name_in_db(name))) { - ut_a(strcmp(table_name, name) == 0); + ut_a(memcmp(table_name, name, namelen) == 0); table = dict_table_get_low(table_name); From 981f6ef9792b51000411a1dc35512adabb609aaf Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Tue, 11 May 2004 11:05:02 +0300 Subject: [PATCH 08/47] InnoDB: Changed bug reporting address to http://bugs.mysql.com --- innobase/btr/btr0btr.c | 2 +- innobase/dict/dict0load.c | 2 +- innobase/ibuf/ibuf0ibuf.c | 7 +++---- innobase/lock/lock0lock.c | 6 ++++-- innobase/row/row0ins.c | 3 +-- innobase/row/row0sel.c | 3 +-- innobase/row/row0umod.c | 3 +-- innobase/row/row0upd.c | 3 +-- innobase/trx/trx0rec.c | 22 +++++++++------------- innobase/ut/ut0dbg.c | 2 +- 10 files changed, 23 insertions(+), 30 deletions(-) diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 70bcd1eea1f..0b4c0dbfa94 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -882,7 +882,7 @@ btr_page_reorganize_low( fprintf(stderr, "InnoDB: Error: page old data size %lu new data size %lu\n" "InnoDB: Error: page old max ins size %lu new max ins size %lu\n" -"InnoDB: Make a detailed bug report and send it to mysql@lists.mysql.com\n", +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", data_size1, data_size2, max_ins_size1, max_ins_size2); } diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 884ef95e183..6a4d4c86824 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -721,7 +721,7 @@ dict_load_table( "InnoDB: the foreign key table or the referenced table!\n" "InnoDB: The data dictionary of InnoDB is corrupt. You may need to drop\n" "InnoDB: and recreate the foreign key table or the referenced table.\n" -"InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" "InnoDB: Latest foreign key error printout:\n%s\n", dict_foreign_err_buf); mutex_exit(&dict_foreign_err_mutex); diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index 83bb23b036f..4525cf7afef 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -2385,7 +2385,7 @@ ibuf_insert_to_index_page( fprintf(stderr, "Bitmap bits %lu\n", old_bits); fputs( -"InnoDB: Send a detailed bug report to mysql@lists.mysql.com!\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } } @@ -2443,7 +2443,7 @@ ibuf_delete_rec( if (!success) { fprintf(stderr, - "InnoDB: ERROR: Send the output to mysql@lists.mysql.com\n" + "InnoDB: ERROR: Submit the output to http://bugs.mysql.com\n" "InnoDB: ibuf cursor restoration fails!\n" "InnoDB: ibuf record inserted to page %lu\n", page_no); fflush(stderr); @@ -2597,8 +2597,7 @@ ibuf_merge_or_delete_for_page( "InnoDB: We try to resolve the problem by skipping the insert buffer\n" "InnoDB: merge for this page. Please run CHECK TABLE on your tables\n" "InnoDB: to determine if they are corrupt after this.\n\n" -"InnoDB: Please make a detailed bug report and send it to\n" -"InnoDB: mysql@lists.mysql.com\n\n", +"InnoDB: Please submit a detailed bug report to http://bugs.mysql.com\n\n", page_no, fil_page_get_type(page)); } } diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 6534387c22c..4343496f6e1 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -1629,7 +1629,8 @@ lock_rec_enqueue_waiting( " InnoDB: Error: a record lock wait happens in a dictionary operation!\n" "InnoDB: Table name ", stderr); ut_print_name(stderr, index->table_name); - fputs(". Send a bug report to mysql@lists.mysql.com\n", + fputs(".\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } @@ -3269,7 +3270,8 @@ lock_table_enqueue_waiting( " InnoDB: Error: a table lock wait happens in a dictionary operation!\n" "InnoDB: Table name ", stderr); ut_print_name(stderr, table->name); - fputs(". Send a bug report to mysql@lists.mysql.com\n", + fputs(".\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 8bc6c9697c1..8f1c1370f25 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -803,8 +803,7 @@ row_ins_foreign_check_on_constraint( "InnoDB: clustered record ", stderr); rec_print(stderr, clust_rec); fputs("\n" - "InnoDB: Make a detailed bug report and send it\n" - "InnoDB: to mysql@lists.mysql.com\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); err = DB_SUCCESS; diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 6f8ce120764..e0bf4684214 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2358,8 +2358,7 @@ row_sel_get_clust_rec_for_mysql( trx_print(stderr, thr_get_trx(thr)); fputs("\n" - "InnoDB: Make a detailed bug report and send it\n" - "InnoDB: to mysql@lists.mysql.com\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } clust_rec = NULL; diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index 5975bb164b9..1f74cfb52be 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -441,8 +441,7 @@ row_undo_mod_del_unmark_sec_and_undo_update( putc('\n', stderr); trx_print(stderr, thr_get_trx(thr)); fputs("\n" - "InnoDB: Make a detailed bug report and send it\n" - "InnoDB: to mysql@lists.mysql.com\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } else { btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur); diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 02fe245ce8b..e7894e543bc 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -1236,8 +1236,7 @@ row_upd_sec_index_entry( trx_print(stderr, thr_get_trx(thr)); fputs("\n" - "InnoDB: Make a detailed bug report and send it\n" - "InnoDB: to mysql@lists.mysql.com\n", stderr); +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } else { /* Delete mark the old index record; it can already be delete marked if we return after a lock wait in diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c index 4926c776ae9..79fad312e8e 100644 --- a/innobase/trx/trx0rec.c +++ b/innobase/trx/trx0rec.c @@ -823,17 +823,16 @@ trx_undo_update_rec_get_update( if (field_no >= dict_index_get_n_fields(index)) { fprintf(stderr, - "InnoDB: Error: trying to access" - " update undo rec field %lu in ", field_no); +"InnoDB: Error: trying to access update undo rec field %lu in ", field_no); dict_index_name_print(stderr, index); fprintf(stderr, "\n" - "InnoDB: but index has only %lu fields\n" - "InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n" - "InnoDB: Run also CHECK TABLE ", +"InnoDB: but index has only %lu fields\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" +"InnoDB: Run also CHECK TABLE ", dict_index_get_n_fields(index)); ut_print_name(stderr, index->table_name); fprintf(stderr, "\n" - "InnoDB: n_fields = %lu, i = %lu, ptr %p\n", +"InnoDB: n_fields = %lu, i = %lu, ptr %p\n", n_fields, i, ptr); return(NULL); } @@ -1271,8 +1270,7 @@ trx_undo_prev_version_build( " update undo rec for non-clustered ", stderr); dict_index_name_print(stderr, index); fputs("\n" - "InnoDB: Send a detailed bug report to" - " mysql@lists.mysql.com\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" "InnoDB: index record ", stderr); rec_print(stderr, index_rec); fputs("\n" @@ -1320,11 +1318,9 @@ trx_undo_prev_version_build( " update undo rec for table ", stderr); ut_print_name(stderr, index->table_name); fputs("\n" - "InnoDB: but the table id in the" - " undo record is wrong\n" - "InnoDB: Send a detailed bug report to " - "mysql@lists.mysql.com\n" - "InnoDB: Run also CHECK TABLE ", stderr); +"InnoDB: but the table id in the undo record is wrong\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n" +"InnoDB: Run also CHECK TABLE ", stderr); ut_print_name(stderr, index->table_name); putc('\n', stderr); } diff --git a/innobase/ut/ut0dbg.c b/innobase/ut/ut0dbg.c index 3697e31050f..65703ec1c86 100644 --- a/innobase/ut/ut0dbg.c +++ b/innobase/ut/ut0dbg.c @@ -23,7 +23,7 @@ const char* ut_dbg_msg_assert_fail = "InnoDB: Assertion failure in thread %lu in file %s line %lu\n"; const char* ut_dbg_msg_trap = "InnoDB: We intentionally generate a memory trap.\n" -"InnoDB: Send a detailed bug report to mysql@lists.mysql.com.\n" +"InnoDB: Submit a detailed bug report to http://bugs.mysql.com.\n" "InnoDB: If you get repeated assertion failures or crashes, even\n" "InnoDB: immediately after the mysqld startup, there may be\n" "InnoDB: corruption in the InnoDB tablespace. See section 6.1 of\n" From 8a03c1b86909ef8c3be811c794b2da85b5a7204a Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 11 May 2004 12:19:37 +0200 Subject: [PATCH 09/47] bug#3612 - Item_func_div set decimals incorrectly --- mysql-test/r/type_float.result | 15 +++++++++++++++ mysql-test/t/type_float.test | 8 ++++++++ sql/item_func.cc | 1 + 3 files changed, 24 insertions(+) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index e85bced353a..c9996e9c9f3 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -67,6 +67,21 @@ select min(a) from t1; min(a) -0.010 drop table t1; +create table t1 (c1 double, c2 varchar(20)); +insert t1 values (121,"16"); +select c1 + c1 * (c2 / 100) as col from t1; +col +140.36 +create table t2 select c1 + c1 * (c2 / 100) as col from t1; +select * from t2; +col +140.36 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `col` double default NULL +) TYPE=MyISAM +drop table t1,t2; create table t1 (f float, f2 float(24), f3 float(6,2), d double, d2 float(53), d3 double(10,3), de decimal, de2 decimal(6), de3 decimal(5,2), n numeric, n2 numeric(8), n3 numeric(5,6)); show full columns from t1; Field Type Null Key Default Extra Privileges diff --git a/mysql-test/t/type_float.test b/mysql-test/t/type_float.test index 23941ad2913..65d594387b9 100644 --- a/mysql-test/t/type_float.test +++ b/mysql-test/t/type_float.test @@ -28,6 +28,14 @@ select a from t1 order by a; select min(a) from t1; drop table t1; +create table t1 (c1 double, c2 varchar(20)); +insert t1 values (121,"16"); +select c1 + c1 * (c2 / 100) as col from t1; +create table t2 select c1 + c1 * (c2 / 100) as col from t1; +select * from t2; +show create table t2; +drop table t1,t2; + # # FLOAT/DOUBLE/DECIMAL handling # diff --git a/sql/item_func.cc b/sql/item_func.cc index 9d1f784fc25..368c14cc8df 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -402,6 +402,7 @@ longlong Item_func_div::val_int() void Item_func_div::fix_length_and_dec() { decimals=max(args[0]->decimals,args[1]->decimals)+2; + set_if_smaller(decimals, NOT_FIXED_DEC); max_length=args[0]->max_length - args[0]->decimals + decimals; uint tmp=float_length(decimals); set_if_smaller(max_length,tmp); From 593a10178e7e44a3ba45b36e60669b18f749463d Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 12 May 2004 01:23:27 +0200 Subject: [PATCH 10/47] - Bumped up version number from 4.0.19 -> 4.0.20 - Tagged ChangeSet@1.1800.1.1 as "mysql-4.0.19" --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index a50d89c8655..b8d279d2f27 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.0.19) +AM_INIT_AUTOMAKE(mysql, 4.0.20) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From ecdac0a326d16ae03f033627ffed37bc093b1469 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Wed, 12 May 2004 10:40:04 +0300 Subject: [PATCH 11/47] eval0eval.c: Backport suppression of MSVC++ warning from 4.1 --- innobase/eval/eval0eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/innobase/eval/eval0eval.c b/innobase/eval/eval0eval.c index 053a10b3c23..a3cd60b86ae 100644 --- a/innobase/eval/eval0eval.c +++ b/innobase/eval/eval0eval.c @@ -725,7 +725,7 @@ eval_predefined( uint_val = (ulint) int_val; } for (tmp = int_len; uint_val > 0; uint_val /= 10) { - data[--tmp] = '0' + (uint_val % 10); + data[--tmp] = '0' + (byte)(uint_val % 10); } } From 17d5da7e33c44057345d984d15d0270e3316d666 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Wed, 12 May 2004 16:44:53 +0300 Subject: [PATCH 12/47] InnoDB: avoid some data races in innobase_mysql_print_thd() (Bug #3596) --- sql/ha_innodb.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index ac7ccf5c11a..8651125e331 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -323,9 +323,10 @@ innobase_mysql_print_thd( FILE* f, /* in: output stream */ void* input_thd)/* in: pointer to a MySQL THD object */ { - THD* thd; + const THD* thd; + const char* s; - thd = (THD*) input_thd; + thd = (const THD*) input_thd; fprintf(f, "MySQL thread id %lu, query id %lu", thd->thread_id, thd->query_id); @@ -344,14 +345,14 @@ innobase_mysql_print_thd( fputs(thd->user, f); } - if (thd->proc_info) { + if ((s = thd->proc_info)) { putc(' ', f); - fputs(thd->proc_info, f); + fputs(s, f); } - if (thd->query) { + if ((s = thd->query)) { putc(' ', f); - fputs(thd->query, f); + fputs(s, f); } putc('\n', f); From c838192066f5e6b593fac803c58d45176e587b0c Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Thu, 13 May 2004 15:28:56 +0300 Subject: [PATCH 13/47] InnoDB: Remove os_file_lock() from the 4.0 tree (unfix Bug #3608) --- innobase/os/os0file.c | 41 ----------------------------------------- 1 file changed, 41 deletions(-) diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 833703e38dd..81566337218 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -358,32 +358,6 @@ os_file_handle_error( return(FALSE); } -#if !defined(__WIN__) && !defined(UNIV_HOTBACKUP) -/******************************************************************** -Obtain an exclusive lock on a file. */ -static -int -os_file_lock( -/*=========*/ - /* out: 0 on success */ - int fd, /* in: file descriptor */ - const char* name) /* in: file name */ -{ - struct flock lk; - lk.l_type = F_WRLCK; - lk.l_whence = SEEK_SET; - lk.l_start = lk.l_len = 0; - if (fcntl(fd, F_SETLK, &lk) == -1) { - fprintf(stderr, - "InnoDB: Unable to lock %s", name); - perror (": fcntl"); - close(fd); - return(-1); - } - return 0; -} -#endif /* !defined(__WIN__) && !defined(UNIV_HOTBACKUP) */ - /******************************************************************** Creates the seek mutexes used in positioned reads and writes. */ @@ -504,11 +478,6 @@ try_again: if (retry) { goto try_again; } -#ifndef UNIV_HOTBACKUP - } else if (os_file_lock(file, name)) { - *success = FALSE; - file = -1; -#endif } else { *success = TRUE; } @@ -603,11 +572,6 @@ os_file_create_simple_no_error_handling( if (file == -1) { *success = FALSE; -#ifndef UNIV_HOTBACKUP - } else if (os_file_lock(file, name)) { - *success = FALSE; - file = -1; -#endif } else { *success = TRUE; } @@ -808,11 +772,6 @@ try_again: if (retry) { goto try_again; } -#ifndef UNIV_HOTBACKUP - } else if (os_file_lock(file, name)) { - *success = FALSE; - file = -1; -#endif } else { *success = TRUE; } From bd8901fd735433838219c064bbfbc2e525e4cfd3 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Thu, 13 May 2004 15:51:02 +0300 Subject: [PATCH 14/47] InnoDB: fixed bug in dict0dict.c: dict_index_name_print() --- innobase/dict/dict0dict.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index fa80532a32d..51e92a9900f 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -4195,5 +4195,5 @@ dict_index_name_print( fputs("index ", file); ut_print_name(file, index->name); fputs(" of table ", file); - ut_print_name(stderr, index->table_name); + ut_print_name(file, index->table_name); } From 077f0812fc40427e0186067ac2faaa8d77b4b845 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Thu, 13 May 2004 16:18:39 +0300 Subject: [PATCH 15/47] ha_innodb.cc: innobase_mysql_print_thd(): protect thd with LOCK_thread_count (Bug #3596) --- sql/ha_innodb.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 8651125e331..d5bbeb874ad 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -328,6 +328,8 @@ innobase_mysql_print_thd( thd = (const THD*) input_thd; + VOID(pthread_mutex_lock(&LOCK_thread_count)); + fprintf(f, "MySQL thread id %lu, query id %lu", thd->thread_id, thd->query_id); if (thd->host) { @@ -351,11 +353,16 @@ innobase_mysql_print_thd( } if ((s = thd->query)) { - putc(' ', f); - fputs(s, f); + /* determine the length of the query string */ + uint32 i, len = thd->query_length; + for (i = 0; i < len && s[i]; i++); + putc('\n', f); + fwrite(s, 1, i, f); } putc('\n', f); + + VOID(pthread_mutex_unlock(&LOCK_thread_count)); } /************************************************************************* From b1f2932fff656fecc020283dee9bf7ecbb4bace6 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Thu, 13 May 2004 18:50:09 +0200 Subject: [PATCH 16/47] - make sure the binaries are executable before calling them during make_binary_distribution (bug#2857) --- scripts/make_binary_distribution.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index c7945e31eda..730086bbb62 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -221,6 +221,7 @@ $CP mysql-test/t/*test mysql-test/t/*.opt mysql-test/t/*.slave-mi mysql-test/t/* $CP mysql-test/r/*result mysql-test/r/*.require $BASE/mysql-test/r if [ $BASE_SYSTEM != "netware" ] ; then + chmod a+x $BASE/bin/* $CP scripts/* $BASE/bin $BASE/bin/replace \@localstatedir\@ ./data \@bindir\@ ./bin \@scriptdir\@ ./bin \@libexecdir\@ ./bin \@sbindir\@ ./bin \@prefix\@ . \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/scripts/mysql_install_db.sh > $BASE/scripts/mysql_install_db $BASE/bin/replace \@prefix\@ /usr/local/mysql \@bindir\@ ./bin \@MYSQLD_USER\@ root \@localstatedir\@ /usr/local/mysql/data \@HOSTNAME\@ @HOSTNAME@ < $SOURCE/support-files/mysql.server.sh > $BASE/support-files/mysql.server From cafad010a608e8abe98187f16fcc274451a71b97 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 13 May 2004 20:02:05 +0300 Subject: [PATCH 17/47] ha_innodb.cc: A flawed fix of the thd->query race in SHOW INNODB STATUS; see the comments in code about how to fix this properly; we cannot use LOCK_thread_count to protect thd->query, because that will cause a deadlock of threads --- sql/ha_innodb.cc | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index d5bbeb874ad..e330a0b532f 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -325,10 +325,18 @@ innobase_mysql_print_thd( { const THD* thd; const char* s; + char buf[301]; thd = (const THD*) input_thd; - VOID(pthread_mutex_lock(&LOCK_thread_count)); +/* We cannot use LOCK_thread_count to protect this operation because we own +the InnoDB kernel_mutex when we enter this function, but in freeing of a +THD object, MySQL first reserves LOCK_thread_count and AFTER THAT InnoDB +reserves kernel_mutex when freeing the trx object => a deadlock can occur. +The solution is for MySQL to use a separate mutex to protect thd->query and +thd->query_len. Someone should do that! This bug has been here for 3 years! + + VOID(pthread_mutex_lock(&LOCK_thread_count)); */ fprintf(f, "MySQL thread id %lu, query id %lu", thd->thread_id, thd->query_id); @@ -354,15 +362,29 @@ innobase_mysql_print_thd( if ((s = thd->query)) { /* determine the length of the query string */ - uint32 i, len = thd->query_length; + uint32 i, len; + + len = thd->query_length; + + if (len > 300) { + len = 300; /* A TEMPORARY SOLUTION: print at most + 300 chars to reduce the probability of + a seg fault in a race */ + } + for (i = 0; i < len && s[i]; i++); + + memcpy(buf, s, i); /* use memcpy to reduce the timeframe + for a race, compared to fwrite() */ + buf[300] = '\0'; + putc('\n', f); - fwrite(s, 1, i, f); + fwrite(buf, 1, i, f); } putc('\n', f); - VOID(pthread_mutex_unlock(&LOCK_thread_count)); +/* VOID(pthread_mutex_unlock(&LOCK_thread_count)); */ } /************************************************************************* From d2649c110a3779196d0873378024a3c26d1a17f4 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 13 May 2004 22:07:51 +0300 Subject: [PATCH 18/47] ha_innodb.cc, trx0trx.h, lock0lock.c, trx0trx.c: Reserve the MySQL LOCK_thread_count mutex when printing thd->query of an arbitrary transaction; if we are printing thd->query of a transaction that we know is currently executing inside InnoDB, then we know that MySQL cannot meanwhile change thd->query, and no need to reserve the MySQL mutex; note that this patch still leaves open the possibility of races in MySQL's thd->query_len --- innobase/include/trx0trx.h | 6 +++-- innobase/lock/lock0lock.c | 34 +++++++++++++++++++++++++++ innobase/trx/trx0trx.c | 4 +++- sql/ha_innodb.cc | 48 +++++++++++++++++++++++++++----------- 4 files changed, 75 insertions(+), 17 deletions(-) diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 71269cb1e4e..07d5e5a8215 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -275,13 +275,15 @@ trx_commit_step( que_thr_t* thr); /* in: query thread */ /************************************************************************** Prints info about a transaction to the standard output. The caller must -own the kernel mutex. */ +own the kernel mutex and must have called +innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL or +InnoDB cannot meanwhile change the info printed here. */ void trx_print( /*======*/ FILE* f, /* in: output stream */ - trx_t* trx); /* in: transaction */ + trx_t* trx); /* in: transaction */ /* Signal to a transaction */ diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 4343496f6e1..791b81366b2 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -17,6 +17,32 @@ Created 5/7/1996 Heikki Tuuri #include "dict0mem.h" #include "trx0sys.h" + +/* 2 function prototypes copied from ha_innodb.cc: */ + +/***************************************************************** +If you want to print a thd that is not associated with the current thread, +you must call this function before reserving the InnoDB kernel_mutex, to +protect MySQL from setting thd->query NULL. If you print a thd of the current +thread, we know that MySQL cannot modify thd->query, and it is not necessary +to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release +the kernel_mutex. +NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this +function! */ + +void +innobase_mysql_prepare_print_arbitrary_thd(void); +/*============================================*/ + +/***************************************************************** +Relases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd(). +NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this +function! */ + +void +innobase_mysql_end_print_arbitrary_thd(void); +/*========================================*/ + /* Restricts the length of search we will do in the waits-for graph of transactions */ #define LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK 1000000 @@ -3974,6 +4000,11 @@ lock_print_info( ulint i; mtr_t mtr; + /* We must protect the MySQL thd->query field with a MySQL mutex, and + because the MySQL mutex must be reserved before the kernel_mutex of + InnoDB, we call innobase_mysql_prepare_print_arbitrary_thd() here. */ + + innobase_mysql_prepare_print_arbitrary_thd(); lock_mutex_enter_kernel(); if (lock_deadlock_found) { @@ -4037,6 +4068,7 @@ loop: if (trx == NULL) { lock_mutex_exit_kernel(); + innobase_mysql_end_print_arbitrary_thd(); ut_ad(lock_validate()); @@ -4101,6 +4133,7 @@ loop: if (load_page_first) { lock_mutex_exit_kernel(); + innobase_mysql_end_print_arbitrary_thd(); mtr_start(&mtr); @@ -4110,6 +4143,7 @@ loop: load_page_first = FALSE; + innobase_mysql_prepare_print_arbitrary_thd(); lock_mutex_enter_kernel(); goto loop; diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 69cd6c7b22d..335e1f69228 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -1562,7 +1562,9 @@ trx_mark_sql_stat_end( /************************************************************************** Prints info about a transaction to the standard output. The caller must -own the kernel mutex. */ +own the kernel mutex and must have called +innobase_mysql_prepare_print_arbitrary_thd(), unless he knows that MySQL or +InnoDB cannot meanwhile change the info printed here. */ void trx_print( diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index e330a0b532f..194c8b558f0 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -312,6 +312,35 @@ convert_error_code_to_mysql( } } +/***************************************************************** +If you want to print a thd that is not associated with the current thread, +you must call this function before reserving the InnoDB kernel_mutex, to +protect MySQL from setting thd->query NULL. If you print a thd of the current +thread, we know that MySQL cannot modify thd->query, and it is not necessary +to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release +the kernel_mutex. +NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this +function! */ +extern "C" +void +innobase_mysql_prepare_print_arbitrary_thd(void) +/*============================================*/ +{ + VOID(pthread_mutex_lock(&LOCK_thread_count)); +} + +/***************************************************************** +Relases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd(). +NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this +function! */ +extern "C" +void +innobase_mysql_end_print_arbitrary_thd(void) +/*========================================*/ +{ + VOID(pthread_mutex_unlock(&LOCK_thread_count)); +} + /***************************************************************** Prints info of a THD object (== user session thread) to the standard output. NOTE that /mysql/innobase/trx/trx0trx.c must contain @@ -329,15 +358,6 @@ innobase_mysql_print_thd( thd = (const THD*) input_thd; -/* We cannot use LOCK_thread_count to protect this operation because we own -the InnoDB kernel_mutex when we enter this function, but in freeing of a -THD object, MySQL first reserves LOCK_thread_count and AFTER THAT InnoDB -reserves kernel_mutex when freeing the trx object => a deadlock can occur. -The solution is for MySQL to use a separate mutex to protect thd->query and -thd->query_len. Someone should do that! This bug has been here for 3 years! - - VOID(pthread_mutex_lock(&LOCK_thread_count)); */ - fprintf(f, "MySQL thread id %lu, query id %lu", thd->thread_id, thd->query_id); if (thd->host) { @@ -367,14 +387,16 @@ thd->query_len. Someone should do that! This bug has been here for 3 years! len = thd->query_length; if (len > 300) { - len = 300; /* A TEMPORARY SOLUTION: print at most + len = 300; /* ADDITIONAL SAFETY: print at most 300 chars to reduce the probability of - a seg fault in a race */ + a seg fault if there is a race in + thd->query_len in MySQL; on May 13, + 2004 we do not know */ } for (i = 0; i < len && s[i]; i++); - memcpy(buf, s, i); /* use memcpy to reduce the timeframe + memcpy(buf, s, i); /* Use memcpy to reduce the timeframe for a race, compared to fwrite() */ buf[300] = '\0'; @@ -383,8 +405,6 @@ thd->query_len. Someone should do that! This bug has been here for 3 years! } putc('\n', f); - -/* VOID(pthread_mutex_unlock(&LOCK_thread_count)); */ } /************************************************************************* From b4ae2577f03888995cb5a78a4bd532d0272349f6 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Fri, 14 May 2004 12:26:12 +0300 Subject: [PATCH 19/47] InnoDB: Remove unused function ut_str_catenate() --- innobase/include/ut0mem.h | 11 ----------- innobase/ut/ut0mem.c | 26 -------------------------- 2 files changed, 37 deletions(-) diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index bfda5ded40c..e83b2e6f60c 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -108,17 +108,6 @@ ut_memcpyq( const char* src, /* in: string to be quoted */ ulint len); /* in: length of src */ -/************************************************************************** -Catenates two strings into newly allocated memory. The memory must be freed -using mem_free. */ - -char* -ut_str_catenate( -/*============*/ - /* out, own: catenated null-terminated string */ - char* str1, /* in: null-terminated string */ - char* str2); /* in: null-terminated string */ - #ifndef UNIV_NONINL #include "ut0mem.ic" #endif diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index 1fcaf9febbe..13846630818 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -236,29 +236,3 @@ ut_memcpyq( return(dest); } - -/************************************************************************** -Catenates two strings into newly allocated memory. The memory must be freed -using mem_free. */ - -char* -ut_str_catenate( -/*============*/ - /* out, own: catenated null-terminated string */ - char* str1, /* in: null-terminated string */ - char* str2) /* in: null-terminated string */ -{ - ulint len1; - ulint len2; - char* str; - - len1 = ut_strlen(str1); - len2 = ut_strlen(str2); - - str = mem_alloc(len1 + len2 + 1); - - ut_memcpy(str, str1, len1); - ut_memcpy(str + len1, str2, len2 + 1); - - return(str); -} From 67f1c04ffcb140403a43dfb2c1b1d65b18f25d26 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Fri, 14 May 2004 12:49:18 +0200 Subject: [PATCH 20/47] better fix for bug#3749 - do not consider already removed keys in key removal process --- mysql-test/r/innodb.result | 25 ++++++++++++++++++++++++- mysql-test/t/innodb.test | 12 +++++++++++- sql/sql_table.cc | 19 ++++++------------- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 60280715911..259e1fb3059 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1540,4 +1540,27 @@ t2 CREATE TABLE `t2` ( drop table t2; create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb; ERROR HY000: Can't create table './test/t2.frm' (errno: 150) -drop table t1; +create table t2 (a int auto_increment primary key, b int, index(b), foreign key (b) references t1(id), unique(b)) engine=innodb; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) NOT NULL auto_increment, + `b` int(11) default NULL, + PRIMARY KEY (`a`), + UNIQUE KEY `b_2` (`b`), + KEY `b` (`b`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t2; +create table t2 (a int auto_increment primary key, b int, foreign key (b) references t1(id), foreign key (b) references t1(id), unique(b)) engine=innodb; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) NOT NULL auto_increment, + `b` int(11) default NULL, + PRIMARY KEY (`a`), + UNIQUE KEY `b` (`b`), + CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`id`), + CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`b`) REFERENCES `t1` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t2, t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index a260ab1263d..babfdcb535f 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1086,4 +1086,14 @@ drop table t2; --error 1005 create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb; -drop table t1; +# bug#3749 + +create table t2 (a int auto_increment primary key, b int, index(b), foreign key (b) references t1(id), unique(b)) engine=innodb; +show create table t2; +drop table t2; +create table t2 (a int auto_increment primary key, b int, foreign key (b) references t1(id), foreign key (b) references t1(id), unique(b)) engine=innodb; +show create table t2; +drop table t2, t1; + + + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 47574eab666..8d5ec56add9 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -688,9 +688,10 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, 'generated', and a generated key is a prefix of the other key. Then we do not need the generated shorter key. */ - if ((key2->type != Key::FOREIGN_KEY && !foreign_key_prefix(key, key2))) + if (key2->name != ignore_key && key2->type != Key::FOREIGN_KEY && + !foreign_key_prefix(key, key2)) { - /* TO DO: issue warning message */ + /* TODO: issue warning message */ /* mark that the generated key should be ignored */ if (!key2->generated || (key->generated && key->columns.elements < @@ -698,17 +699,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key->name= ignore_key; else { - /* - Remove the previous, generated key if it has not yet been - removed. Note that if we have several identical generated keys, - the last one will remain and others get removed here. - */ - if (key2->name != ignore_key) - { - key2->name= ignore_key; - key_parts-= key2->columns.elements; - (*key_count)--; - } + key2->name= ignore_key; + key_parts-= key2->columns.elements; + (*key_count)--; } break; } From a5cca9df64f72d857135a7136330fd069b4bb159 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Fri, 14 May 2004 16:06:21 +0300 Subject: [PATCH 21/47] InnoDB cleanup: eliminate IB__FILE__ --- innobase/btr/btr0cur.c | 6 +-- innobase/btr/btr0sea.c | 4 +- innobase/buf/buf0buf.c | 8 +-- innobase/ibuf/ibuf0ibuf.c | 2 +- innobase/include/buf0buf.h | 14 ++--- innobase/include/buf0buf.ic | 2 +- innobase/include/mem0mem.h | 96 ++++++++++++++++++----------------- innobase/include/mem0mem.ic | 96 +++++++++++++++++------------------ innobase/include/mtr0mtr.h | 8 +-- innobase/include/mtr0mtr.ic | 4 +- innobase/include/pars0pars.h | 2 +- innobase/include/sync0arr.h | 2 +- innobase/include/sync0ipm.ic | 4 +- innobase/include/sync0rw.h | 44 ++++++++-------- innobase/include/sync0rw.ic | 22 ++++---- innobase/include/sync0sync.h | 16 +++--- innobase/include/sync0sync.ic | 8 +-- innobase/include/univ.i | 5 -- innobase/include/ut0dbg.h | 6 +-- innobase/lock/lock0lock.c | 2 +- innobase/log/log0recv.c | 6 +-- innobase/mem/mem0mem.c | 34 ++++++------- innobase/pars/pars0pars.c | 3 +- innobase/sync/sync0arr.c | 4 +- innobase/sync/sync0rw.c | 12 ++--- innobase/sync/sync0sync.c | 13 ++--- innobase/trx/trx0rec.c | 2 +- 27 files changed, 212 insertions(+), 213 deletions(-) diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index e67d1d76113..5829cc2c406 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -399,7 +399,7 @@ btr_cur_search_to_nth_level( retry_page_get: page = buf_page_get_gen(space, page_no, rw_latch, guess, buf_mode, - IB__FILE__, __LINE__, + __FILE__, __LINE__, mtr); if (page == NULL) { /* This must be a search to perform an insert; @@ -580,7 +580,7 @@ btr_cur_open_at_index_side( for (;;) { page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL, BUF_GET, - IB__FILE__, __LINE__, + __FILE__, __LINE__, mtr); ut_ad(0 == ut_dulint_cmp(tree->id, btr_page_get_index_id(page))); @@ -689,7 +689,7 @@ btr_cur_open_at_rnd_pos( for (;;) { page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL, BUF_GET, - IB__FILE__, __LINE__, + __FILE__, __LINE__, mtr); ut_ad(0 == ut_dulint_cmp(tree->id, btr_page_get_index_id(page))); diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c index f2b03f9f348..9384168df88 100644 --- a/innobase/btr/btr0sea.c +++ b/innobase/btr/btr0sea.c @@ -764,7 +764,7 @@ btr_search_guess_on_hash( success = buf_page_get_known_nowait(latch_mode, page, BUF_MAKE_YOUNG, - IB__FILE__, __LINE__, + __FILE__, __LINE__, mtr); rw_lock_s_unlock(&btr_search_latch); @@ -1048,7 +1048,7 @@ btr_search_drop_page_hash_when_freed( having to fear a deadlock. */ page = buf_page_get_gen(space, page_no, RW_S_LATCH, NULL, - BUF_GET_IF_IN_POOL, IB__FILE__, __LINE__, + BUF_GET_IF_IN_POOL, __FILE__, __LINE__, &mtr); #ifdef UNIV_SYNC_DEBUG diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index 7a5ef3c5e14..4d83fb4c9f2 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -1048,7 +1048,7 @@ buf_page_get_gen( buf_frame_t* guess, /* in: guessed frame or NULL */ ulint mode, /* in: BUF_GET, BUF_GET_IF_IN_POOL, BUF_GET_NO_LATCH, BUF_GET_NOWAIT */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line where called */ mtr_t* mtr) /* in: mini-transaction */ { @@ -1257,7 +1257,7 @@ buf_page_optimistic_get_func( frames */ dulint modify_clock,/* in: modify clock value if mode is ..._GUESS_ON_CLOCK */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line where called */ mtr_t* mtr) /* in: mini-transaction */ { @@ -1382,7 +1382,7 @@ buf_page_get_known_nowait( ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */ buf_frame_t* guess, /* in: the known page frame */ ulint mode, /* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line where called */ mtr_t* mtr) /* in: mini-transaction */ { @@ -1742,7 +1742,7 @@ buf_page_create( buf_LRU_add_block(block, FALSE); #ifdef UNIV_SYNC_DEBUG - buf_block_buf_fix_inc_debug(block, IB__FILE__, __LINE__); + buf_block_buf_fix_inc_debug(block, __FILE__, __LINE__); #else buf_block_buf_fix_inc(block); #endif diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index ecdcf08e4c6..7dc0bd98001 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -3042,7 +3042,7 @@ loop: if (page) { ibool success = buf_page_get_known_nowait(RW_X_LATCH, page, BUF_KEEP_OLD, - IB__FILE__, __LINE__, + __FILE__, __LINE__, &mtr); ut_a(success); #ifdef UNIV_SYNC_DEBUG diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index 6b8da886045..9590fea1276 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -132,7 +132,7 @@ to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed in LA! */ #define buf_page_get(SP, OF, LA, MTR) buf_page_get_gen(\ SP, OF, LA, NULL,\ - BUF_GET, IB__FILE__, __LINE__, MTR) + BUF_GET, __FILE__, __LINE__, MTR) /****************************************************************** Use these macros to bufferfix a page with no latching. Remember not to read the contents of the page unless you know it is safe. Do not modify @@ -141,19 +141,19 @@ error-prone programming not to set a latch, and it should be used with care. */ #define buf_page_get_with_no_latch(SP, OF, MTR) buf_page_get_gen(\ SP, OF, RW_NO_LATCH, NULL,\ - BUF_GET_NO_LATCH, IB__FILE__, __LINE__, MTR) + BUF_GET_NO_LATCH, __FILE__, __LINE__, MTR) /****************************************************************** NOTE! The following macros should be used instead of buf_page_get_gen, to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed as LA! */ #define buf_page_get_nowait(SP, OF, LA, MTR) buf_page_get_gen(\ SP, OF, LA, NULL,\ - BUF_GET_NOWAIT, IB__FILE__, __LINE__, MTR) + BUF_GET_NOWAIT, __FILE__, __LINE__, MTR) /****************************************************************** NOTE! The following macros should be used instead of buf_page_optimistic_get_func, to improve debugging. Only values RW_S_LATCH and RW_X_LATCH are allowed as LA! */ #define buf_page_optimistic_get(LA, BL, G, MC, MTR) buf_page_optimistic_get_func(\ - LA, BL, G, MC, IB__FILE__, __LINE__, MTR) + LA, BL, G, MC, __FILE__, __LINE__, MTR) /************************************************************************ This is the general function used to get optimistic access to a database page. */ @@ -168,7 +168,7 @@ buf_page_optimistic_get_func( frames */ dulint modify_clock,/* in: modify clock value if mode is ..._GUESS_ON_CLOCK */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line where called */ mtr_t* mtr); /* in: mini-transaction */ /************************************************************************ @@ -201,7 +201,7 @@ buf_page_get_known_nowait( ulint rw_latch,/* in: RW_S_LATCH, RW_X_LATCH */ buf_frame_t* guess, /* in: the known page frame */ ulint mode, /* in: BUF_MAKE_YOUNG or BUF_KEEP_OLD */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line where called */ mtr_t* mtr); /* in: mini-transaction */ /************************************************************************ @@ -217,7 +217,7 @@ buf_page_get_gen( buf_frame_t* guess, /* in: guessed frame or NULL */ ulint mode, /* in: BUF_GET, BUF_GET_IF_IN_POOL, BUF_GET_NO_LATCH */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line where called */ mtr_t* mtr); /* in: mini-transaction */ /************************************************************************ diff --git a/innobase/include/buf0buf.ic b/innobase/include/buf0buf.ic index b644afcbdff..4d1173a0d7f 100644 --- a/innobase/include/buf0buf.ic +++ b/innobase/include/buf0buf.ic @@ -585,7 +585,7 @@ buf_page_get_release_on_io( frame = buf_page_get_gen(space, offset, rw_latch, guess, BUF_GET_IF_IN_POOL, - IB__FILE__, __LINE__, + __FILE__, __LINE__, mtr); if (frame != NULL) { diff --git a/innobase/include/mem0mem.h b/innobase/include/mem0mem.h index 89e2a337c99..18bffe5732e 100644 --- a/innobase/include/mem0mem.h +++ b/innobase/include/mem0mem.h @@ -64,14 +64,14 @@ heap creation. */ #define mem_heap_create(N) mem_heap_create_func(\ (N), NULL, MEM_HEAP_DYNAMIC,\ - IB__FILE__, __LINE__) + __FILE__, __LINE__) /****************************************************************** Use this macro instead of the corresponding function! Macro for memory heap creation. */ #define mem_heap_create_in_buffer(N) mem_heap_create_func(\ (N), NULL, MEM_HEAP_BUFFER,\ - IB__FILE__, __LINE__) + __FILE__, __LINE__) /****************************************************************** Use this macro instead of the corresponding function! Macro for memory heap creation. */ @@ -79,7 +79,7 @@ heap creation. */ #define mem_heap_create_in_btr_search(N) mem_heap_create_func(\ (N), NULL, MEM_HEAP_BTR_SEARCH |\ MEM_HEAP_BUFFER,\ - IB__FILE__, __LINE__) + __FILE__, __LINE__) /****************************************************************** Use this macro instead of the corresponding function! Macro for fast memory heap creation. An initial block of memory B is given by the @@ -88,14 +88,14 @@ mem_heap_free. See the parameter comment in mem_heap_create_func below. */ #define mem_heap_fast_create(N, B) mem_heap_create_func(\ (N), (B), MEM_HEAP_DYNAMIC,\ - IB__FILE__, __LINE__) + __FILE__, __LINE__) /****************************************************************** Use this macro instead of the corresponding function! Macro for memory heap freeing. */ #define mem_heap_free(heap) mem_heap_free_func(\ - (heap), IB__FILE__, __LINE__) + (heap), __FILE__, __LINE__) /********************************************************************* NOTE: Use the corresponding macros instead of this function. Creates a memory heap which allocates memory from dynamic space. For debugging @@ -105,26 +105,27 @@ UNIV_INLINE mem_heap_t* mem_heap_create_func( /*=================*/ - /* out, own: memory heap */ - ulint n, /* in: desired start block size, - this means that a single user buffer - of size n will fit in the block, - 0 creates a default size block; - if init_block is not NULL, n tells - its size in bytes */ - void* init_block, /* in: if very fast creation is - wanted, the caller can reserve some - memory from its stack, for example, - and pass it as the the initial block - to the heap: then no OS call of malloc - is needed at the creation. CAUTION: - the caller must make sure the initial - block is not unintentionally erased - (if allocated in the stack), before - the memory heap is explicitly freed. */ - ulint type, /* in: MEM_HEAP_DYNAMIC or MEM_HEAP_BUFFER */ - char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ + /* out, own: memory heap */ + ulint n, /* in: desired start block size, + this means that a single user buffer + of size n will fit in the block, + 0 creates a default size block; + if init_block is not NULL, n tells + its size in bytes */ + void* init_block, /* in: if very fast creation is + wanted, the caller can reserve some + memory from its stack, for example, + and pass it as the the initial block + to the heap: then no OS call of malloc + is needed at the creation. CAUTION: + the caller must make sure the initial + block is not unintentionally erased + (if allocated in the stack), before + the memory heap is explicitly freed. */ + ulint type, /* in: MEM_HEAP_DYNAMIC + or MEM_HEAP_BUFFER */ + const char* file_name, /* in: file name where created */ + ulint line /* in: line where created */ ); /********************************************************************* NOTE: Use the corresponding macro instead of this function. Frees the space @@ -135,7 +136,7 @@ void mem_heap_free_func( /*===============*/ mem_heap_t* heap, /* in, own: heap to be freed */ - char* file_name __attribute__((unused)), + const char* file_name __attribute__((unused)), /* in: file name where freed */ ulint line __attribute__((unused))); /* in: line where freed */ @@ -206,13 +207,13 @@ mem_heap_get_size( Use this macro instead of the corresponding function! Macro for memory buffer allocation */ -#define mem_alloc(N) mem_alloc_func((N), IB__FILE__, __LINE__) +#define mem_alloc(N) mem_alloc_func((N), __FILE__, __LINE__) /****************************************************************** Use this macro instead of the corresponding function! Macro for memory buffer allocation */ #define mem_alloc_noninline(N) mem_alloc_func_noninline(\ - (N), IB__FILE__, __LINE__) + (N), __FILE__, __LINE__) /******************************************************************* NOTE: Use the corresponding macro instead of this function. Allocates a single buffer of memory from the dynamic memory of @@ -222,11 +223,11 @@ UNIV_INLINE void* mem_alloc_func( /*===========*/ - /* out, own: free storage, NULL - if did not succeed */ - ulint n, /* in: desired number of bytes */ - char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ + /* out, own: free storage, NULL + if did not succeed */ + ulint n, /* in: desired number of bytes */ + const char* file_name, /* in: file name where created */ + ulint line /* in: line where created */ ); /******************************************************************* NOTE: Use the corresponding macro instead of this function. @@ -237,17 +238,17 @@ with mem_free. */ void* mem_alloc_func_noninline( /*=====================*/ - /* out, own: free storage, NULL if did not - succeed */ - ulint n, /* in: desired number of bytes */ - char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ + /* out, own: free storage, + NULL if did not succeed */ + ulint n, /* in: desired number of bytes */ + const char* file_name, /* in: file name where created */ + ulint line /* in: line where created */ ); /****************************************************************** Use this macro instead of the corresponding function! Macro for memory buffer freeing */ -#define mem_free(PTR) mem_free_func((PTR), IB__FILE__, __LINE__) +#define mem_free(PTR) mem_free_func((PTR), __FILE__, __LINE__) /******************************************************************* NOTE: Use the corresponding macro instead of this function. Frees a single buffer of storage from @@ -256,9 +257,9 @@ UNIV_INLINE void mem_free_func( /*==========*/ - void* ptr, /* in, own: buffer to be freed */ - char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ + void* ptr, /* in, own: buffer to be freed */ + const char* file_name, /* in: file name where created */ + ulint line /* in: line where created */ ); /******************************************************************* Implements realloc. */ @@ -266,11 +267,12 @@ UNIV_INLINE void* mem_realloc( /*========*/ - /* out, own: free storage, NULL if did not succeed */ - void* buf, /* in: pointer to an old buffer */ - ulint n, /* in: desired number of bytes */ - char* file_name,/* in: file name where called */ - ulint line); /* in: line where called */ + /* out, own: free storage, + NULL if did not succeed */ + void* buf, /* in: pointer to an old buffer */ + ulint n, /* in: desired number of bytes */ + const char* file_name, /* in: file name where called */ + ulint line); /* in: line where called */ /************************************************************************** Duplicates a NUL-terminated string. */ diff --git a/innobase/include/mem0mem.ic b/innobase/include/mem0mem.ic index c250e6948ec..df3dbf9b576 100644 --- a/innobase/include/mem0mem.ic +++ b/innobase/include/mem0mem.ic @@ -16,18 +16,18 @@ Creates a memory heap block where data can be allocated. */ mem_block_t* mem_heap_create_block( /*==================*/ - /* out, own: memory heap block, NULL if did not - succeed */ - mem_heap_t* heap,/* in: memory heap or NULL if first block should - be created */ - ulint n, /* in: number of bytes needed for user data, or - if init_block is not NULL, its size in bytes */ - void* init_block, /* in: init block in fast create, type must be - MEM_HEAP_DYNAMIC */ - ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC or - MEM_HEAP_BUFFER */ - char* file_name,/* in: file name where created */ - ulint line); /* in: line where created */ + /* out, own: memory heap block, + NULL if did not succeed */ + mem_heap_t* heap, /* in: memory heap or NULL if first block + should be created */ + ulint n, /* in: number of bytes needed for user data, or + if init_block is not NULL, its size in bytes */ + void* init_block, /* in: init block in fast create, + type must be MEM_HEAP_DYNAMIC */ + ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC or + MEM_HEAP_BUFFER */ + const char* file_name,/* in: file name where created */ + ulint line); /* in: line where created */ /********************************************************************** Frees a block from a memory heap. */ @@ -377,27 +377,27 @@ UNIV_INLINE mem_heap_t* mem_heap_create_func( /*=================*/ - /* out, own: memory heap */ - ulint n, /* in: desired start block size, - this means that a single user buffer - of size n will fit in the block, - 0 creates a default size block; - if init_block is not NULL, n tells - its size in bytes */ - void* init_block, /* in: if very fast creation is - wanted, the caller can reserve some - memory from its stack, for example, - and pass it as the the initial block - to the heap: then no OS call of malloc - is needed at the creation. CAUTION: - the caller must make sure the initial - block is not unintentionally erased - (if allocated in the stack), before - the memory heap is explicitly freed. */ - ulint type, /* in: MEM_HEAP_DYNAMIC, or MEM_HEAP_BUFFER - possibly ORed to MEM_HEAP_BTR_SEARCH */ - char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ + /* out, own: memory heap */ + ulint n, /* in: desired start block size, + this means that a single user buffer + of size n will fit in the block, + 0 creates a default size block; + if init_block is not NULL, n tells + its size in bytes */ + void* init_block, /* in: if very fast creation is + wanted, the caller can reserve some + memory from its stack, for example, + and pass it as the the initial block + to the heap: then no OS call of malloc + is needed at the creation. CAUTION: + the caller must make sure the initial + block is not unintentionally erased + (if allocated in the stack), before + the memory heap is explicitly freed. */ + ulint type, /* in: MEM_HEAP_DYNAMIC + or MEM_HEAP_BUFFER */ + const char* file_name, /* in: file name where created */ + ulint line /* in: line where created */ ) { mem_block_t* block; @@ -440,10 +440,9 @@ void mem_heap_free_func( /*===============*/ mem_heap_t* heap, /* in, own: heap to be freed */ - char* file_name __attribute__((unused)), + const char* file_name __attribute__((unused)), /* in: file name where freed */ ulint line __attribute__((unused))) - /* in: line where freed */ { mem_block_t* block; mem_block_t* prev_block; @@ -486,11 +485,11 @@ UNIV_INLINE void* mem_alloc_func( /*===========*/ - /* out, own: free storage, NULL if did not - succeed */ - ulint n, /* in: desired number of bytes */ - char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ + /* out, own: free storage, NULL + if did not succeed */ + ulint n, /* in: desired number of bytes */ + const char* file_name, /* in: file name where created */ + ulint line /* in: line where created */ ) { mem_heap_t* heap; @@ -523,9 +522,9 @@ UNIV_INLINE void mem_free_func( /*==========*/ - void* ptr, /* in, own: buffer to be freed */ - char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ + void* ptr, /* in, own: buffer to be freed */ + const char* file_name, /* in: file name where created */ + ulint line /* in: line where created */ ) { mem_heap_t* heap; @@ -569,11 +568,12 @@ UNIV_INLINE void* mem_realloc( /*========*/ - /* out, own: free storage, NULL if did not succeed */ - void* buf, /* in: pointer to an old buffer */ - ulint n, /* in: desired number of bytes */ - char* file_name,/* in: file name where called */ - ulint line) /* in: line where called */ + /* out, own: free storage, + NULL if did not succeed */ + void* buf, /* in: pointer to an old buffer */ + ulint n, /* in: desired number of bytes */ + const char* file_name, /* in: file name where called */ + ulint line) /* in: line where called */ { mem_free(buf); diff --git a/innobase/include/mtr0mtr.h b/innobase/include/mtr0mtr.h index 73338977b9c..f6dfe23bc41 100644 --- a/innobase/include/mtr0mtr.h +++ b/innobase/include/mtr0mtr.h @@ -198,11 +198,11 @@ mtr_read_dulint( mtr_t* mtr); /* in: mini-transaction handle */ /************************************************************************* This macro locks an rw-lock in s-mode. */ -#define mtr_s_lock(B, MTR) mtr_s_lock_func((B), IB__FILE__, __LINE__,\ +#define mtr_s_lock(B, MTR) mtr_s_lock_func((B), __FILE__, __LINE__,\ (MTR)) /************************************************************************* This macro locks an rw-lock in x-mode. */ -#define mtr_x_lock(B, MTR) mtr_x_lock_func((B), IB__FILE__, __LINE__,\ +#define mtr_x_lock(B, MTR) mtr_x_lock_func((B), __FILE__, __LINE__,\ (MTR)) /************************************************************************* NOTE! Use the macro above! @@ -212,7 +212,7 @@ void mtr_s_lock_func( /*============*/ rw_lock_t* lock, /* in: rw-lock */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line number */ mtr_t* mtr); /* in: mtr */ /************************************************************************* @@ -223,7 +223,7 @@ void mtr_x_lock_func( /*============*/ rw_lock_t* lock, /* in: rw-lock */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line number */ mtr_t* mtr); /* in: mtr */ diff --git a/innobase/include/mtr0mtr.ic b/innobase/include/mtr0mtr.ic index 51112fc0d14..4fc6dd2f6a9 100644 --- a/innobase/include/mtr0mtr.ic +++ b/innobase/include/mtr0mtr.ic @@ -217,7 +217,7 @@ void mtr_s_lock_func( /*============*/ rw_lock_t* lock, /* in: rw-lock */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line number */ mtr_t* mtr) /* in: mtr */ { @@ -236,7 +236,7 @@ void mtr_x_lock_func( /*============*/ rw_lock_t* lock, /* in: rw-lock */ - char* file, /* in: file name */ + const char* file, /* in: file name */ ulint line, /* in: line number */ mtr_t* mtr) /* in: mtr */ { diff --git a/innobase/include/pars0pars.h b/innobase/include/pars0pars.h index 2e86a7e5534..c260557c424 100644 --- a/innobase/include/pars0pars.h +++ b/innobase/include/pars0pars.h @@ -92,7 +92,7 @@ Called by yyparse on error. */ void yyerror( /*====*/ - char* s); /* in: error message string */ + const char* s); /* in: error message string */ /************************************************************************* Parses a variable declaration. */ diff --git a/innobase/include/sync0arr.h b/innobase/include/sync0arr.h index 383d0c69fb2..e7d511f8137 100644 --- a/innobase/include/sync0arr.h +++ b/innobase/include/sync0arr.h @@ -51,7 +51,7 @@ sync_array_reserve_cell( sync_array_t* arr, /* in: wait array */ void* object, /* in: pointer to the object to wait for */ ulint type, /* in: lock request type */ - char* file, /* in: file where requested */ + const char* file, /* in: file where requested */ ulint line, /* in: line where requested */ ulint* index); /* out: index of the reserved cell */ /********************************************************************** diff --git a/innobase/include/sync0ipm.ic b/innobase/include/sync0ipm.ic index b8aa87ba6d6..126aceae1eb 100644 --- a/innobase/include/sync0ipm.ic +++ b/innobase/include/sync0ipm.ic @@ -92,7 +92,7 @@ loop: loop_count++; ut_ad(loop_count < 15); - if (mutex_enter_nowait(mutex, IB__FILE__, __LINE__) == 0) { + if (mutex_enter_nowait(mutex, __FILE__, __LINE__) == 0) { /* Succeeded! */ return(0); @@ -105,7 +105,7 @@ loop: /* Order is important here: FIRST reset event, then set waiters */ ip_mutex_set_waiters(ip_mutex, 1); - if (mutex_enter_nowait(mutex, IB__FILE__, __LINE__) == 0) { + if (mutex_enter_nowait(mutex, __FILE__, __LINE__) == 0) { /* Succeeded! */ return(0); diff --git a/innobase/include/sync0rw.h b/innobase/include/sync0rw.h index 82123a529a3..63b01ffac80 100644 --- a/innobase/include/sync0rw.h +++ b/innobase/include/sync0rw.h @@ -62,7 +62,7 @@ location (which must be appropriately aligned). The rw-lock is initialized to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free is necessary only if the memory block containing it is freed. */ -#define rw_lock_create(L) rw_lock_create_func((L), IB__FILE__, __LINE__) +#define rw_lock_create(L) rw_lock_create_func((L), __FILE__, __LINE__) /*=====================*/ /********************************************************************** Creates, or rather, initializes an rw-lock object in a specified memory @@ -74,7 +74,7 @@ void rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ - char* cfile_name, /* in: file name where created */ + const char* cfile_name, /* in: file name where created */ ulint cline); /* in: file line where created */ /********************************************************************** Calling this function is obligatory only if the memory buffer containing @@ -100,19 +100,19 @@ NOTE! The following macros should be used in rw s-locking, not the corresponding function. */ #define rw_lock_s_lock(M) rw_lock_s_lock_func(\ - (M), 0, IB__FILE__, __LINE__) + (M), 0, __FILE__, __LINE__) /****************************************************************** NOTE! The following macros should be used in rw s-locking, not the corresponding function. */ #define rw_lock_s_lock_gen(M, P) rw_lock_s_lock_func(\ - (M), (P), IB__FILE__, __LINE__) + (M), (P), __FILE__, __LINE__) /****************************************************************** NOTE! The following macros should be used in rw s-locking, not the corresponding function. */ #define rw_lock_s_lock_nowait(M) rw_lock_s_lock_func_nowait(\ - (M), IB__FILE__, __LINE__) + (M), __FILE__, __LINE__) /********************************************************************** NOTE! Use the corresponding macro, not directly this function, except if you supply the file name and line number. Lock an rw-lock in shared mode @@ -127,7 +127,7 @@ rw_lock_s_lock_func( rw_lock_t* lock, /* in: pointer to rw-lock */ ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - char* file_name,/* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line); /* in: line where requested */ /********************************************************************** NOTE! Use the corresponding macro, not directly this function, except if @@ -139,7 +139,7 @@ rw_lock_s_lock_func_nowait( /*=======================*/ /* out: TRUE if success */ rw_lock_t* lock, /* in: pointer to rw-lock */ - char* file_name,/* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line); /* in: line where requested */ /********************************************************************** NOTE! Use the corresponding macro, not directly this function! Lock an @@ -151,7 +151,7 @@ rw_lock_x_lock_func_nowait( /*=======================*/ /* out: TRUE if success */ rw_lock_t* lock, /* in: pointer to rw-lock */ - char* file_name,/* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line); /* in: line where requested */ /********************************************************************** Releases a shared mode lock. */ @@ -186,19 +186,19 @@ NOTE! The following macro should be used in rw x-locking, not the corresponding function. */ #define rw_lock_x_lock(M) rw_lock_x_lock_func(\ - (M), 0, IB__FILE__, __LINE__) + (M), 0, __FILE__, __LINE__) /****************************************************************** NOTE! The following macro should be used in rw x-locking, not the corresponding function. */ #define rw_lock_x_lock_gen(M, P) rw_lock_x_lock_func(\ - (M), (P), IB__FILE__, __LINE__) + (M), (P), __FILE__, __LINE__) /****************************************************************** NOTE! The following macros should be used in rw x-locking, not the corresponding function. */ #define rw_lock_x_lock_nowait(M) rw_lock_x_lock_func_nowait(\ - (M), IB__FILE__, __LINE__) + (M), __FILE__, __LINE__) /********************************************************************** NOTE! Use the corresponding macro, not directly this function! Lock an rw-lock in exclusive mode for the current thread. If the rw-lock is locked @@ -215,7 +215,7 @@ rw_lock_x_lock_func( rw_lock_t* lock, /* in: pointer to rw-lock */ ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - char* file_name,/* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line); /* in: line where requested */ /********************************************************************** Releases an exclusive mode lock. */ @@ -253,9 +253,9 @@ UNIV_INLINE void rw_lock_s_lock_direct( /*==================*/ - rw_lock_t* lock /* in: pointer to rw-lock */ - ,char* file_name, /* in: file name where lock requested */ - ulint line /* in: line where requested */ + rw_lock_t* lock, /* in: pointer to rw-lock */ + const char* file_name, /* in: file name where requested */ + ulint line /* in: line where lock requested */ ); /********************************************************************** Low-level function which locks an rw-lock in x-mode when we know that it @@ -265,9 +265,9 @@ UNIV_INLINE void rw_lock_x_lock_direct( /*==================*/ - rw_lock_t* lock /* in: pointer to rw-lock */ - ,char* file_name, /* in: file name where lock requested */ - ulint line /* in: line where requested */ + rw_lock_t* lock, /* in: pointer to rw-lock */ + const char* file_name, /* in: file name where requested */ + ulint line /* in: line where lock requested */ ); /********************************************************************** This function is used in the insert buffer to move the ownership of an @@ -451,10 +451,10 @@ struct rw_lock_struct { #endif /* UNIV_SYNC_DEBUG */ ulint level; /* Level in the global latching order; default SYNC_LEVEL_NONE */ - char* cfile_name; /* File name where lock created */ + const char* cfile_name;/* File name where lock created */ ulint cline; /* Line where created */ - char* last_s_file_name;/* File name where last time s-locked */ - char* last_x_file_name;/* File name where last time x-locked */ + const char* last_s_file_name;/* File name where last s-locked */ + const char* last_x_file_name;/* File name where last x-locked */ ulint last_s_line; /* Line number where last time s-locked */ ulint last_x_line; /* Line number where last time x-locked */ ulint magic_n; @@ -471,7 +471,7 @@ struct rw_lock_debug_struct { ulint pass; /* Pass value given in the lock operation */ ulint lock_type; /* Type of the lock: RW_LOCK_EX, RW_LOCK_SHARED, RW_LOCK_WAIT_EX */ - char* file_name; /* File name where the lock was obtained */ + const char* file_name;/* File name where the lock was obtained */ ulint line; /* Line where the rw-lock was locked */ UT_LIST_NODE_T(rw_lock_debug_t) list; /* Debug structs are linked in a two-way diff --git a/innobase/include/sync0rw.ic b/innobase/include/sync0rw.ic index 8fc93f4a9da..655bd7f6517 100644 --- a/innobase/include/sync0rw.ic +++ b/innobase/include/sync0rw.ic @@ -18,7 +18,7 @@ rw_lock_s_lock_spin( rw_lock_t* lock, /* in: pointer to rw-lock */ ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - char* file_name,/* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line); /* in: line where requested */ #ifdef UNIV_SYNC_DEBUG /********************************************************************** @@ -130,7 +130,7 @@ rw_lock_s_lock_low( ulint pass __attribute__((unused)), /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - char* file_name, /* in: file name where lock requested */ + const char* file_name, /* in: file name where lock requested */ ulint line) /* in: line where requested */ { #ifdef UNIV_SYNC_DEBUG @@ -163,9 +163,9 @@ UNIV_INLINE void rw_lock_s_lock_direct( /*==================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ - char* file_name,/* in: file name where lock requested */ - ulint line) /* in: line where requested */ + rw_lock_t* lock, /* in: pointer to rw-lock */ + const char* file_name, /* in: file name where requested */ + ulint line) /* in: line where lock requested */ { ut_ad(lock->writer == RW_LOCK_NOT_LOCKED); ut_ad(rw_lock_get_reader_count(lock) == 0); @@ -189,9 +189,9 @@ UNIV_INLINE void rw_lock_x_lock_direct( /*==================*/ - rw_lock_t* lock, /* in: pointer to rw-lock */ - char* file_name, /* in: file name where lock requested */ - ulint line) /* in: line where requested */ + rw_lock_t* lock, /* in: pointer to rw-lock */ + const char* file_name, /* in: file name where requested */ + ulint line) /* in: line where lock requested */ { ut_ad(rw_lock_validate(lock)); ut_ad(rw_lock_get_reader_count(lock) == 0); @@ -223,7 +223,7 @@ rw_lock_s_lock_func( rw_lock_t* lock, /* in: pointer to rw-lock */ ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - char* file_name, /* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line) /* in: line where requested */ { /* NOTE: As we do not know the thread ids for threads which have @@ -267,7 +267,7 @@ rw_lock_s_lock_func_nowait( /*=======================*/ /* out: TRUE if success */ rw_lock_t* lock, /* in: pointer to rw-lock */ - char* file_name,/* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line) /* in: line where requested */ { ibool success = FALSE; @@ -304,7 +304,7 @@ rw_lock_x_lock_func_nowait( /*=======================*/ /* out: TRUE if success */ rw_lock_t* lock, /* in: pointer to rw-lock */ - char* file_name, /* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line) /* in: line where requested */ { ibool success = FALSE; diff --git a/innobase/include/sync0sync.h b/innobase/include/sync0sync.h index 0cc48d5f299..4307ca5ba0c 100644 --- a/innobase/include/sync0sync.h +++ b/innobase/include/sync0sync.h @@ -36,7 +36,7 @@ in the reset state. Explicit freeing of the mutex with mutex_free is necessary only if the memory block containing it is freed. */ -#define mutex_create(M) mutex_create_func((M), IB__FILE__, __LINE__) +#define mutex_create(M) mutex_create_func((M), __FILE__, __LINE__) /*===================*/ /********************************************************************** Creates, or rather, initializes a mutex object in a specified memory @@ -48,7 +48,7 @@ void mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ - char* cfile_name, /* in: file name where created */ + const char* cfile_name, /* in: file name where created */ ulint cline); /* in: file line where created */ /********************************************************************** Calling this function is obligatory only if the memory buffer containing @@ -64,7 +64,7 @@ mutex_free( NOTE! The following macro should be used in mutex locking, not the corresponding function. */ -#define mutex_enter(M) mutex_enter_func((M), IB__FILE__, __LINE__) +#define mutex_enter(M) mutex_enter_func((M), __FILE__, __LINE__) /********************************************************************** A noninlined function that reserves a mutex. In ha_innodb.cc we have disabled inlining of InnoDB functions, and no inlined functions should be called from @@ -80,7 +80,7 @@ corresponding function. */ /* NOTE! currently same as mutex_enter! */ -#define mutex_enter_fast(M) mutex_enter_func((M), IB__FILE__, __LINE__) +#define mutex_enter_fast(M) mutex_enter_func((M), __FILE__, __LINE__) #define mutex_enter_fast_func mutex_enter_func; /********************************************************************** NOTE! Use the corresponding macro in the header file, not this function @@ -92,7 +92,7 @@ void mutex_enter_func( /*=============*/ mutex_t* mutex, /* in: pointer to mutex */ - char* file_name, /* in: file name where locked */ + const char* file_name, /* in: file name where locked */ ulint line); /* in: line where locked */ /************************************************************************ Tries to lock the mutex for the current thread. If the lock is not acquired @@ -103,9 +103,9 @@ mutex_enter_nowait( /*===============*/ /* out: 0 if succeed, 1 if not */ mutex_t* mutex, /* in: pointer to mutex */ - char* file_name, /* in: file name where mutex + const char* file_name, /* in: file name where mutex requested */ - ulint line); /* in: line where requested */ + ulint line); /* in: line where requested */ /********************************************************************** Unlocks a mutex owned by the current thread. */ UNIV_INLINE @@ -470,7 +470,7 @@ struct mutex_struct { #endif /* UNIV_SYNC_DEBUG */ ulint level; /* Level in the global latching order; default SYNC_LEVEL_NONE */ - char* cfile_name; /* File name where mutex created */ + const char* cfile_name;/* File name where mutex created */ ulint cline; /* Line where created */ ulint magic_n; }; diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic index 758c8524f66..ecb498918e2 100644 --- a/innobase/include/sync0sync.ic +++ b/innobase/include/sync0sync.ic @@ -23,7 +23,7 @@ void mutex_spin_wait( /*============*/ mutex_t* mutex, /* in: pointer to mutex */ - char* file_name,/* in: file name where mutex requested */ + const char* file_name,/* in: file name where mutex requested */ ulint line); /* in: line where requested */ #ifdef UNIV_SYNC_DEBUG /********************************************************************** @@ -241,9 +241,9 @@ UNIV_INLINE void mutex_enter_func( /*=============*/ - mutex_t* mutex, /* in: pointer to mutex */ - char* file_name,/* in: file name where locked */ - ulint line) /* in: line where locked */ + mutex_t* mutex, /* in: pointer to mutex */ + const char* file_name, /* in: file name where locked */ + ulint line) /* in: line where locked */ { ut_ad(mutex_validate(mutex)); diff --git a/innobase/include/univ.i b/innobase/include/univ.i index cd471a89607..be71d4211b3 100644 --- a/innobase/include/univ.i +++ b/innobase/include/univ.i @@ -242,11 +242,6 @@ contains the sum of the following flag and the locally stored len. */ #define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE) -/* The following definition of __FILE__ removes compiler warnings -associated with const char* / char* mismatches with __FILE__ */ - -#define IB__FILE__ ((char*)__FILE__) - #include #include "ut0dbg.h" #include "ut0ut.h" diff --git a/innobase/include/ut0dbg.h b/innobase/include/ut0dbg.h index 085b4811a73..a155f68bd12 100644 --- a/innobase/include/ut0dbg.h +++ b/innobase/include/ut0dbg.h @@ -27,7 +27,7 @@ extern const char* ut_dbg_msg_stop; if (!((ulint)(EXPR) + ut_dbg_zero)) {\ ut_print_timestamp(stderr);\ fprintf(stderr, ut_dbg_msg_assert_fail,\ - os_thread_pf(os_thread_get_curr_id()), IB__FILE__,\ + os_thread_pf(os_thread_get_curr_id()), __FILE__,\ (ulint)__LINE__);\ fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\ fputs(ut_dbg_msg_trap, stderr);\ @@ -36,7 +36,7 @@ extern const char* ut_dbg_msg_stop; }\ if (ut_dbg_stop_threads) {\ fprintf(stderr, ut_dbg_msg_stop,\ - os_thread_pf(os_thread_get_curr_id()), IB__FILE__, (ulint)__LINE__);\ + os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\ os_thread_sleep(1000000000);\ }\ } while (0) @@ -44,7 +44,7 @@ extern const char* ut_dbg_msg_stop; #define ut_error do {\ ut_print_timestamp(stderr);\ fprintf(stderr, ut_dbg_msg_assert_fail,\ - os_thread_pf(os_thread_get_curr_id()), IB__FILE__, (ulint)__LINE__);\ + os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\ fprintf(stderr, ut_dbg_msg_trap);\ ut_dbg_stop_threads = TRUE;\ if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\ diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 8805a22bb57..056d502e858 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -3889,7 +3889,7 @@ lock_rec_print( page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL, BUF_GET_IF_IN_POOL, - IB__FILE__, __LINE__, &mtr); + __FILE__, __LINE__, &mtr); if (page) { page = buf_page_get_nowait(space, page_no, RW_S_LATCH, &mtr); diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 4f4220962f0..65fb3466ad5 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -1080,7 +1080,7 @@ recv_recover_page( success = buf_page_get_known_nowait(RW_X_LATCH, page, BUF_KEEP_OLD, - IB__FILE__, __LINE__, + __FILE__, __LINE__, &mtr); ut_a(success); @@ -1664,7 +1664,7 @@ recv_compare_spaces( frame = buf_page_get_gen(space1, page_no, RW_S_LATCH, NULL, BUF_GET_IF_IN_POOL, - IB__FILE__, __LINE__, + __FILE__, __LINE__, &mtr); if (frame) { #ifdef UNIV_SYNC_DEBUG @@ -1679,7 +1679,7 @@ recv_compare_spaces( frame = buf_page_get_gen(space2, page_no, RW_S_LATCH, NULL, BUF_GET_IF_IN_POOL, - IB__FILE__, __LINE__, + __FILE__, __LINE__, &mtr); if (frame) { #ifdef UNIV_SYNC_DEBUG diff --git a/innobase/mem/mem0mem.c b/innobase/mem/mem0mem.c index e1b9a762381..c090b25a632 100644 --- a/innobase/mem/mem0mem.c +++ b/innobase/mem/mem0mem.c @@ -92,11 +92,11 @@ with mem_free. */ void* mem_alloc_func_noninline( /*=====================*/ - /* out, own: free storage, NULL if did not - succeed */ - ulint n, /* in: desired number of bytes */ - char* file_name, /* in: file name where created */ - ulint line /* in: line where created */ + /* out, own: free storage, + NULL if did not succeed */ + ulint n, /* in: desired number of bytes */ + const char* file_name, /* in: file name where created */ + ulint line /* in: line where created */ ) { return(mem_alloc_func(n, file_name, line)); @@ -108,18 +108,18 @@ Creates a memory heap block where data can be allocated. */ mem_block_t* mem_heap_create_block( /*==================*/ - /* out, own: memory heap block, NULL if did not - succeed */ - mem_heap_t* heap,/* in: memory heap or NULL if first block should - be created */ - ulint n, /* in: number of bytes needed for user data, or - if init_block is not NULL, its size in bytes */ - void* init_block, /* in: init block in fast create, type must be - MEM_HEAP_DYNAMIC */ - ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC, or - MEM_HEAP_BUFFER possibly ORed to MEM_HEAP_BTR_SEARCH */ - char* file_name,/* in: file name where created */ - ulint line) /* in: line where created */ + /* out, own: memory heap block, + NULL if did not succeed */ + mem_heap_t* heap, /* in: memory heap or NULL if first block + should be created */ + ulint n, /* in: number of bytes needed for user data, or + if init_block is not NULL, its size in bytes */ + void* init_block, /* in: init block in fast create, + type must be MEM_HEAP_DYNAMIC */ + ulint type, /* in: type of heap: MEM_HEAP_DYNAMIC or + MEM_HEAP_BUFFER */ + const char* file_name,/* in: file name where created */ + ulint line) /* in: line where created */ { mem_block_t* block; ulint len; diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c index a4124672df0..7e835d9ada1 100644 --- a/innobase/pars/pars0pars.c +++ b/innobase/pars/pars0pars.c @@ -1713,7 +1713,8 @@ Called by yyparse on error. */ void yyerror( /*====*/ - char* s __attribute__((unused))) /* in: error message string */ + const char* s __attribute__((unused))) + /* in: error message string */ { ut_ad(s); diff --git a/innobase/sync/sync0arr.c b/innobase/sync/sync0arr.c index 426d7ff9f92..02a9771be35 100644 --- a/innobase/sync/sync0arr.c +++ b/innobase/sync/sync0arr.c @@ -53,7 +53,7 @@ struct sync_cell_struct { rw_lock_t* old_wait_rw_lock;/* the latest wait rw-lock in cell */ ulint request_type; /* lock type requested on the object */ - char* file; /* in debug version file where + const char* file; /* in debug version file where requested */ ulint line; /* in debug version line where requested */ @@ -329,7 +329,7 @@ sync_array_reserve_cell( sync_array_t* arr, /* in: wait array */ void* object, /* in: pointer to the object to wait for */ ulint type, /* in: lock request type */ - char* file, /* in: file where requested */ + const char* file, /* in: file where requested */ ulint line, /* in: line where requested */ ulint* index) /* out: index of the reserved cell */ { diff --git a/innobase/sync/sync0rw.c b/innobase/sync/sync0rw.c index 43f8d646eaa..769eb326ce2 100644 --- a/innobase/sync/sync0rw.c +++ b/innobase/sync/sync0rw.c @@ -89,7 +89,7 @@ void rw_lock_create_func( /*================*/ rw_lock_t* lock, /* in: pointer to memory */ - char* cfile_name, /* in: file name where created */ + const char* cfile_name, /* in: file name where created */ ulint cline) /* in: file line where created */ { /* If this is the very first time a synchronization @@ -213,7 +213,7 @@ rw_lock_s_lock_spin( rw_lock_t* lock, /* in: pointer to rw-lock */ ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - char* file_name, /* in: file name where lock requested */ + const char* file_name, /* in: file name where lock requested */ ulint line) /* in: line where requested */ { ulint index; /* index of the reserved wait cell */ @@ -324,7 +324,7 @@ rw_lock_x_lock_low( rw_lock_t* lock, /* in: pointer to rw-lock */ ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - char* file_name,/* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line) /* in: line where requested */ { #ifdef UNIV_SYNC_DEBUG @@ -429,7 +429,7 @@ rw_lock_x_lock_func( rw_lock_t* lock, /* in: pointer to rw-lock */ ulint pass, /* in: pass value; != 0, if the lock will be passed to another thread to unlock */ - char* file_name,/* in: file name where lock requested */ + const char* file_name,/* in: file name where lock requested */ ulint line) /* in: line where requested */ { ulint index; /* index of the reserved wait cell */ @@ -551,7 +551,7 @@ rw_lock_debug_mutex_enter(void) { loop: if (0 == mutex_enter_nowait(&rw_lock_debug_mutex, - IB__FILE__, __LINE__)) { + __FILE__, __LINE__)) { return; } @@ -560,7 +560,7 @@ loop: rw_lock_debug_waiters = TRUE; if (0 == mutex_enter_nowait(&rw_lock_debug_mutex, - IB__FILE__, __LINE__)) { + __FILE__, __LINE__)) { return; } diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index c1fb31bc966..31f287b6341 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -201,7 +201,7 @@ void mutex_create_func( /*==============*/ mutex_t* mutex, /* in: pointer to memory */ - char* cfile_name, /* in: file name where created */ + const char* cfile_name, /* in: file name where created */ ulint cline) /* in: file line where created */ { #if defined(_WIN32) && defined(UNIV_CAN_USE_X86_ASSEMBLER) @@ -294,10 +294,10 @@ mutex_enter_nowait( /*===============*/ /* out: 0 if succeed, 1 if not */ mutex_t* mutex, /* in: pointer to mutex */ - char* file_name __attribute__((unused)), + const char* file_name __attribute__((unused)), /* in: file name where mutex requested */ - ulint line __attribute__((unused))) + ulint line __attribute__((unused))) /* in: line where requested */ { ut_ad(mutex_validate(mutex)); @@ -357,9 +357,10 @@ for the mutex before suspending the thread. */ void mutex_spin_wait( /*============*/ - mutex_t* mutex, /* in: pointer to mutex */ - char* file_name, /* in: file name where mutex requested */ - ulint line) /* in: line where requested */ + mutex_t* mutex, /* in: pointer to mutex */ + const char* file_name, /* in: file name where + mutex requested */ + ulint line) /* in: line where requested */ { ulint index; /* index of the reserved wait cell */ ulint i; /* spin round count */ diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c index 7963bec7f33..16f9f3d093d 100644 --- a/innobase/trx/trx0rec.c +++ b/innobase/trx/trx0rec.c @@ -1067,7 +1067,7 @@ trx_undo_report_row_operation( undo_page = buf_page_get_gen(undo->space, page_no, RW_X_LATCH, undo->guess_page, BUF_GET, - IB__FILE__, __LINE__, + __FILE__, __LINE__, &mtr); #ifdef UNIV_SYNC_DEBUG From 02f51ccf2d16bd3525e1446553ab74c00af695f1 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Fri, 14 May 2004 16:48:56 +0300 Subject: [PATCH 22/47] Many files: Fix remaining cases of Bug #3596: fix possible races caused by an obsolete value of thd->query_length in SHOW PROCESSLIST and SHOW INNODB STATUS; this fix depends on the fact that thd->query is always set to NULL before setting it to point to a new query --- sql/ha_innodb.cc | 7 ++++--- sql/log_event.cc | 1 + sql/slave.cc | 2 ++ sql/sql_class.h | 19 ++++++++++++++++++- sql/sql_db.cc | 2 ++ sql/sql_parse.cc | 1 + sql/sql_show.cc | 6 +++++- 7 files changed, 33 insertions(+), 5 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 194c8b558f0..4835f794a1d 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -390,15 +390,16 @@ innobase_mysql_print_thd( len = 300; /* ADDITIONAL SAFETY: print at most 300 chars to reduce the probability of a seg fault if there is a race in - thd->query_len in MySQL; on May 13, - 2004 we do not know */ + thd->query_length in MySQL; after + May 14, 2004 probably no race any more, + but better be safe */ } for (i = 0; i < len && s[i]; i++); memcpy(buf, s, i); /* Use memcpy to reduce the timeframe for a race, compared to fwrite() */ - buf[300] = '\0'; + buf[300] = '\0'; /* not needed, just extra safety */ putc('\n', f); fwrite(buf, 1, i, f); diff --git a/sql/log_event.cc b/sql/log_event.cc index 7817ccff3d7..f84c8d1f579 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1929,6 +1929,7 @@ end: VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->db= 0; // prevent db from being freed thd->query= 0; // just to be sure + thd->query_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); // assume no convert for next query unless set explictly thd->variables.convert_set = 0; diff --git a/sql/slave.cc b/sql/slave.cc index d6d0a5b5425..c7a7dac141a 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2691,6 +2691,7 @@ err: IO_RPL_LOG_NAME, llstr(mi->master_log_pos,llbuff)); VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + thd->query_length = 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (mysql) { @@ -2839,6 +2840,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ err: VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = thd->db = 0; // extra safety + thd->query_length = 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&rli->run_lock); diff --git a/sql/sql_class.h b/sql/sql_class.h index ad1eed5448f..83dc75e2b84 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -360,7 +360,24 @@ public: struct rand_struct rand; // used for authentication struct system_variables variables; // Changeable local variables pthread_mutex_t LOCK_delete; // Locked before thd is deleted - + /* + Note that (A) if we set query = NULL, we must at the same time set + query_length = 0, and protect the whole operation with the + LOCK_thread_count mutex. And (B) we are ONLY allowed to set query to a + non-NULL value if its previous value is NULL. We do not need to protect + operation (B) with any mutex. To avoid crashes in races, if we do not + know that thd->query cannot change at the moment, one should print + thd->query like this: + (1) reserve the LOCK_thread_count mutex; + (2) check if thd->query is NULL; + (3) if not NULL, then print at most thd->query_length characters from + it. We will see the query_length field as either 0, or the right value + for it. + Assuming that the write and read of an n-bit memory field in an n-bit + computer is atomic, we can avoid races in the above way. + This printing is needed at least in SHOW PROCESSLIST and SHOW INNODB + STATUS. + */ char *query; // Points to the current query, /* A pointer to the stack frame of handle_one_connection(), diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 7dd458a3b5d..865b2e1328f 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -95,6 +95,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) { VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query= 0; + thd->query_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); } send_ok(&thd->net, result); @@ -202,6 +203,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query= 0; + thd->query_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); } send_ok(&thd->net,(ulong) deleted); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index be2d81fa372..77032bef698 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1312,6 +1312,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->proc_info=0; thd->command=COM_SLEEP; thd->query=0; + thd->query_length=0; thread_running--; VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 63f3afab128..7f52e52c849 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1141,7 +1141,11 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) thd_info->query=0; if (tmp->query) { - /* query_length is always set before tmp->query */ + /* + query_length is always set to 0 when we set query = NULL; see + the comment in sql_class.h why this prevents crashes in possible + races with query_length + */ uint length= min(max_query_length, tmp->query_length); thd_info->query=(char*) thd->memdup(tmp->query,length+1); thd_info->query[length]=0; From 38d0d362c5147d0bf5f07bf37338a47123b184bf Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Fri, 14 May 2004 16:56:47 +0300 Subject: [PATCH 23/47] SELECT options print fixed --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b847907a1a2..f7a8bce4616 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -9385,7 +9385,7 @@ void st_select_lex::print(THD *thd, String *str) if (!thd->lex->safe_to_cache_query) str->append("sql_no_cache ", 13); if (options & OPTION_TO_QUERY_CACHE) - str->append("cache ", 6); + str->append("sql_cache ", 10); //Item List bool first= 1; From 712d379b5ef56da19f5e1077d46a93d61bb99f1b Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Fri, 14 May 2004 18:55:24 +0300 Subject: [PATCH 24/47] check of item name presence in find_item_in_list (Bug #3752) --- mysql-test/r/func_gconcat.result | 9 +++++++++ mysql-test/t/func_gconcat.test | 10 ++++++++++ sql/sql_base.cc | 9 ++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index fdde8f766a9..11d976b9d15 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -301,3 +301,12 @@ a c grp 2 4 4 1 2 5 drop table t1,t2; +CREATE TABLE t1 ( a int ); +CREATE TABLE t2 ( a int ); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (1), (2); +SELECT GROUP_CONCAT(t1.a*t2.a ORDER BY t1.a) FROM t1, t2 GROUP BY t1.a; +GROUP_CONCAT(t1.a*t2.a ORDER BY t1.a) +2,1 +4,2 +DROP TABLE t1, t2; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 9d99a57afe5..6e1ebe250c1 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -179,3 +179,13 @@ select group_concat(c order by (select mid(group_concat(c order by a),1,5) from select a,c,(select group_concat(c order by a) from t2 where a=t1.a) as grp from t1 order by grp; drop table t1,t2; + +# +# group_concat of expression with GROUP BY and external GROUP BY +# +CREATE TABLE t1 ( a int ); +CREATE TABLE t2 ( a int ); +INSERT INTO t1 VALUES (1), (2); +INSERT INTO t2 VALUES (1), (2); +SELECT GROUP_CONCAT(t1.a*t2.a ORDER BY t1.a) FROM t1, t2 GROUP BY t1.a; +DROP TABLE t1, t2; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3a18b7eaabc..14a54a410a2 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2096,7 +2096,14 @@ find_item_in_list(Item *find, List &items, uint *counter, if (field_name && item->type() == Item::FIELD_ITEM) { Item_field *item_field= (Item_field*) item; - if (!my_strcasecmp(system_charset_info, item_field->name, field_name)) + /* + In case of group_concat() with ORDER BY condition in the QUERY + item_field can be field of temporary table without item name + (if this field created from expression argument of group_concat()), + => we have to check presence of name before compare + */ + if (item_field->name && + !my_strcasecmp(system_charset_info, item_field->name, field_name)) { if (!table_name) { From e81c6e1763bf0d6442c59ef17fcf61af02bf2d1f Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 14 May 2004 21:00:29 +0500 Subject: [PATCH 25/47] CXX linker specified for client_test with libmysqld --- libmysqld/examples/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/libmysqld/examples/Makefile.am b/libmysqld/examples/Makefile.am index b11db65baf6..b3db54d305a 100644 --- a/libmysqld/examples/Makefile.am +++ b/libmysqld/examples/Makefile.am @@ -26,6 +26,7 @@ mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \ my_readline.h sql_string.h completion_hash.h mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) +client_test_LINK = $(CXXLINK) client_test_SOURCES = client_test.c clean: From 6a594c07c58a3a47389e72a8fc2f156f55b01feb Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Fri, 14 May 2004 19:12:09 +0200 Subject: [PATCH 26/47] get rid of remaining strtolls - irix64 compatibility --- sql/sql_yacc.yy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0f29289ac25..d7ef1fc8d7f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4683,8 +4683,8 @@ literal: | TIMESTAMP text_literal { $$ = $2; }; NUM_literal: - NUM { $$ = new Item_int($1.str, (longlong) strtol($1.str, NULL, 10),$1.length); } - | LONG_NUM { $$ = new Item_int($1.str, (longlong) strtoll($1.str,NULL,10), $1.length); } + NUM { int error; $$ = new Item_int($1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); } + | LONG_NUM { int error; $$ = new Item_int($1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); } | ULONGLONG_NUM { $$ = new Item_uint($1.str, $1.length); } | REAL_NUM { $$ = new Item_real($1.str, $1.length); } | FLOAT_NUM { $$ = new Item_float($1.str, $1.length); } From a039062ef372c6e0f68fbeb3c579f96fa591f5c8 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 14 May 2004 23:08:03 +0200 Subject: [PATCH 27/47] Replication testsuite: making the master-slave synchronization less likely to fail, by adding sleep-and-retries (max 4 times) if MASTER_POS_WAIT() returns NULL in sync_with_master and sync_slave_with_master. The problem showed up only today, in MySQL 5.0 in rpl_server_id2.test, but may affect 4.x as well, so fixing it here. Note that I am also fixing 5.0 too, with the same exact patch, because I don't want to leave 5.0 broken until the next 4.0->4.1->5.0 merge. --- client/mysqltest.c | 21 ++++++++++++++++++--- mysql-test/r/rpl_server_id2.result | 1 - mysql-test/t/rpl_server_id2.test | 1 - 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 32fb44d178e..7dae99efde3 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1081,7 +1081,7 @@ int do_sync_with_master2(const char* p) MYSQL_ROW row; MYSQL* mysql = &cur_con->mysql; char query_buf[FN_REFLEN+128]; - int offset = 0; + int offset= 0, tries= 0; int rpl_parse; if (!master_pos.file[0]) @@ -1096,6 +1096,9 @@ int do_sync_with_master2(const char* p) sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file, master_pos.pos + offset); + +wait_for_position: + if (mysql_query(mysql, query_buf)) die("line %u: failed in %s: %d: %s", start_lineno, query_buf, mysql_errno(mysql), mysql_error(mysql)); @@ -1106,8 +1109,20 @@ int do_sync_with_master2(const char* p) if (!(row = mysql_fetch_row(res))) die("line %u: empty result in %s", start_lineno, query_buf); if (!row[0]) - die("line %u: could not sync with master ('%s' returned NULL)", - start_lineno, query_buf); + { + /* + It may be that the slave SQL thread has not started yet, though START + SLAVE has been issued ? + */ + if (tries++ == 3) + { + die("line %u: could not sync with master ('%s' returned NULL)", + start_lineno, query_buf); + } + sleep(1); /* So at most we will wait 3 seconds and make 4 tries */ + mysql_free_result(res); + goto wait_for_position; + } mysql_free_result(res); last_result=0; if (rpl_parse) diff --git a/mysql-test/r/rpl_server_id2.result b/mysql-test/r/rpl_server_id2.result index d665bb25dbb..1b5d946998c 100644 --- a/mysql-test/r/rpl_server_id2.result +++ b/mysql-test/r/rpl_server_id2.result @@ -4,7 +4,6 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -drop table if exists t1; create table t1 (n int); reset master; stop slave; diff --git a/mysql-test/t/rpl_server_id2.test b/mysql-test/t/rpl_server_id2.test index dc8f733b7ed..7bbac358ada 100644 --- a/mysql-test/t/rpl_server_id2.test +++ b/mysql-test/t/rpl_server_id2.test @@ -3,7 +3,6 @@ source include/master-slave.inc; connection slave; -drop table if exists t1; create table t1 (n int); reset master; # replicate ourselves From 1e860400f3a260c01a00bada514df7f34ec462c0 Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Sat, 15 May 2004 09:08:03 +0300 Subject: [PATCH 28/47] Extra safety fixes (probably not needed, but can't hurt) --- sql/ha_innodb.cc | 9 +++------ sql/sql_parse.cc | 3 ++- sql/sql_show.cc | 3 +-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 4835f794a1d..4a50e2d8ccf 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -395,12 +395,9 @@ innobase_mysql_print_thd( but better be safe */ } - for (i = 0; i < len && s[i]; i++); - - memcpy(buf, s, i); /* Use memcpy to reduce the timeframe - for a race, compared to fwrite() */ - buf[300] = '\0'; /* not needed, just extra safety */ - + /* Use strmake to reduce the timeframe + for a race, compared to fwrite() */ + i= (uint) (strmake(buf, s, len) - buf); putc('\n', f); fwrite(buf, 1, i, f); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 77032bef698..7e68db0dcd2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1067,6 +1067,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, packet_length--; } /* We must allocate some extra memory for query cache */ + thd->query_length= 0; // Extra safety: Avoid races if (!(thd->query= (char*) thd->memdup_w_gap((gptr) (packet), packet_length, thd->db_length+2+ @@ -2982,8 +2983,8 @@ void mysql_parse(THD *thd, char *inBuf, uint length) { DBUG_ENTER("mysql_parse"); - mysql_init_query(thd); thd->query_length = length; + mysql_init_query(thd); if (query_cache_send_result_to_client(thd, inBuf, length) <= 0) { LEX *lex=lex_start(thd, (uchar*) inBuf, length); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 7f52e52c849..a4ef735c715 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1147,8 +1147,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) races with query_length */ uint length= min(max_query_length, tmp->query_length); - thd_info->query=(char*) thd->memdup(tmp->query,length+1); - thd_info->query[length]=0; + thd_info->query=(char*) thd->strmake(tmp->query,length); } thread_infos.append(thd_info); } From a785d16d8aefe07274edfb5b7f7f77343907696d Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Sat, 15 May 2004 11:20:43 +0300 Subject: [PATCH 29/47] results fix --- mysql-test/r/func_encrypt.result | 2 +- mysql-test/r/func_gconcat.result | 8 ++++---- mysql-test/t/func_gconcat.test | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_encrypt.result b/mysql-test/r/func_encrypt.result index abdfda0423f..d32e67fe7d5 100644 --- a/mysql-test/r/func_encrypt.result +++ b/mysql-test/r/func_encrypt.result @@ -138,4 +138,4 @@ explain extended select des_decrypt(des_encrypt("hello",4),'password2'), des_dec id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select high_priority des_decrypt(des_encrypt(_latin1'hello',4),_latin1'password2') AS `des_decrypt(des_encrypt("hello",4),'password2')`,des_decrypt(des_encrypt(_latin1'hello',_latin1'hidden')) AS `des_decrypt(des_encrypt("hello","hidden"))` +Note 1003 select des_decrypt(des_encrypt(_latin1'hello',4),_latin1'password2') AS `des_decrypt(des_encrypt("hello",4),'password2')`,des_decrypt(des_encrypt(_latin1'hello',_latin1'hidden')) AS `des_decrypt(des_encrypt("hello","hidden"))` diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 11d976b9d15..60a28e5018f 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -305,8 +305,8 @@ CREATE TABLE t1 ( a int ); CREATE TABLE t2 ( a int ); INSERT INTO t1 VALUES (1), (2); INSERT INTO t2 VALUES (1), (2); -SELECT GROUP_CONCAT(t1.a*t2.a ORDER BY t1.a) FROM t1, t2 GROUP BY t1.a; -GROUP_CONCAT(t1.a*t2.a ORDER BY t1.a) -2,1 -4,2 +SELECT GROUP_CONCAT(t1.a*t2.a ORDER BY t2.a) FROM t1, t2 GROUP BY t1.a; +GROUP_CONCAT(t1.a*t2.a ORDER BY t2.a) +1,2 +2,4 DROP TABLE t1, t2; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index 6e1ebe250c1..aede2220466 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -187,5 +187,5 @@ CREATE TABLE t1 ( a int ); CREATE TABLE t2 ( a int ); INSERT INTO t1 VALUES (1), (2); INSERT INTO t2 VALUES (1), (2); -SELECT GROUP_CONCAT(t1.a*t2.a ORDER BY t1.a) FROM t1, t2 GROUP BY t1.a; +SELECT GROUP_CONCAT(t1.a*t2.a ORDER BY t2.a) FROM t1, t2 GROUP BY t1.a; DROP TABLE t1, t2; From e0a4b51215963a5f10f57f3949b117322dca59cb Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Sat, 15 May 2004 11:57:40 +0300 Subject: [PATCH 30/47] Better fix for bug #3749 (bug in deleting automatic generated foreign keys) --- mysql-test/r/func_encrypt.result | 2 +- mysql-test/r/innodb.result | 31 +++++++++++++++++++++++++++++++ mysql-test/t/innodb.test | 10 ++++++++++ sql/sql_class.cc | 2 +- sql/sql_table.cc | 24 +++++++++--------------- tests/client_test.c | 5 ++--- 6 files changed, 54 insertions(+), 20 deletions(-) diff --git a/mysql-test/r/func_encrypt.result b/mysql-test/r/func_encrypt.result index abdfda0423f..d32e67fe7d5 100644 --- a/mysql-test/r/func_encrypt.result +++ b/mysql-test/r/func_encrypt.result @@ -138,4 +138,4 @@ explain extended select des_decrypt(des_encrypt("hello",4),'password2'), des_dec id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1003 select high_priority des_decrypt(des_encrypt(_latin1'hello',4),_latin1'password2') AS `des_decrypt(des_encrypt("hello",4),'password2')`,des_decrypt(des_encrypt(_latin1'hello',_latin1'hidden')) AS `des_decrypt(des_encrypt("hello","hidden"))` +Note 1003 select des_decrypt(des_encrypt(_latin1'hello',4),_latin1'password2') AS `des_decrypt(des_encrypt("hello",4),'password2')`,des_decrypt(des_encrypt(_latin1'hello',_latin1'hidden')) AS `des_decrypt(des_encrypt("hello","hidden"))` diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 60280715911..cb99f9fe06d 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1538,6 +1538,37 @@ t2 CREATE TABLE `t2` ( CONSTRAINT `t1_id_fk` FOREIGN KEY (`id2`, `id`) REFERENCES `t1` (`id`, `id2`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t2; +create table t2 (id int(11) not null auto_increment, id2 int(11) not null, constraint t1_id_fk foreign key (id) references t1 (id), primary key (id), index (id,id2)) engine = innodb; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL auto_increment, + `id2` int(11) NOT NULL default '0', + PRIMARY KEY (`id`), + KEY `id` (`id`,`id2`), + CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t2; +create table t2 (id int(11) not null auto_increment, id2 int(11) not null, constraint t1_id_fk foreign key (id) references t1 (id)) engine= innodb; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL auto_increment, + `id2` int(11) NOT NULL default '0', + KEY `t1_id_fk` (`id`), + CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +alter table t2 add index id_test (id), add index id_test2 (id,id2); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL auto_increment, + `id2` int(11) NOT NULL default '0', + KEY `id_test` (`id`), + KEY `id_test2` (`id`,`id2`), + CONSTRAINT `t1_id_fk` FOREIGN KEY (`id`) REFERENCES `t1` (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t2; create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb; ERROR HY000: Can't create table './test/t2.frm' (errno: 150) drop table t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index a260ab1263d..36b2914ef46 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1082,6 +1082,16 @@ create table t2 (id int(11) not null, id2 int(11) not null, unique (id,id2),cons show create table t2; drop table t2; +create table t2 (id int(11) not null auto_increment, id2 int(11) not null, constraint t1_id_fk foreign key (id) references t1 (id), primary key (id), index (id,id2)) engine = innodb; +show create table t2; +drop table t2; + +create table t2 (id int(11) not null auto_increment, id2 int(11) not null, constraint t1_id_fk foreign key (id) references t1 (id)) engine= innodb; +show create table t2; +alter table t2 add index id_test (id), add index id_test2 (id,id2); +show create table t2; +drop table t2; + # Test error handling --error 1005 create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 03d67c4f300..f7992c3db9e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -86,7 +86,7 @@ bool key_part_spec::operator==(const key_part_spec& other) const /* - Test if a foreign key is a prefix of the given key + Test if a foreign key (= generated key) is a prefix of the given key (ignoring key name, key type and order of columns) NOTES: diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 47574eab666..284b228567a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -684,11 +684,13 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, while ((key2 = key_iterator2++) != key) { /* - foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is - 'generated', and a generated key is a prefix of the other key. Then we - do not need the generated shorter key. + foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is + 'generated', and a generated key is a prefix of the other key. + Then we do not need the generated shorter key. */ - if ((key2->type != Key::FOREIGN_KEY && !foreign_key_prefix(key, key2))) + if ((key2->type != Key::FOREIGN_KEY && + key2->name != ignore_key && + !foreign_key_prefix(key, key2))) { /* TO DO: issue warning message */ /* mark that the generated key should be ignored */ @@ -698,17 +700,9 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, key->name= ignore_key; else { - /* - Remove the previous, generated key if it has not yet been - removed. Note that if we have several identical generated keys, - the last one will remain and others get removed here. - */ - if (key2->name != ignore_key) - { - key2->name= ignore_key; - key_parts-= key2->columns.elements; - (*key_count)--; - } + key2->name= ignore_key; + key_parts-= key2->columns.elements; + (*key_count)--; } break; } diff --git a/tests/client_test.c b/tests/client_test.c index ba70bcd7fa7..c244274a2e7 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -9614,7 +9614,6 @@ union distinct \ select sum(a) + 200, 1 from t1 \ group by b "); check_stmt(stmt); - mysql_stmt_close(stmt); stmt= mysql_simple_prepare(mysql, @@ -9624,14 +9623,14 @@ union distinct \ select sum(a) + 200, 1 from t1 \ group by b "); check_stmt(stmt); + mysql_stmt_close(stmt); - stmt= mysql_simple_prepare(mysql, + stmt= mysql_simple_prepare(mysql, "select sum(a) + 200, ? from t1 \ union distinct \ select sum(a) + 200, 1 from t1 \ group by b "); check_stmt(stmt); - mysql_stmt_close(stmt); rc= mysql_query(mysql, "DROP TABLE t1"); From da63a927f28a4304afacae15e465e3e40aaa3bce Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Sat, 15 May 2004 11:20:42 +0200 Subject: [PATCH 31/47] bad old merge fixed --- mysql-test/r/order_by.result | 9 +++++++++ mysql-test/t/order_by.test | 10 ++++++++++ sql/sql_select.cc | 1 - 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 1a10c9c6ce9..5edffdacc98 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -85,6 +85,15 @@ i 1 3 drop table t1; +create table t1 ( pk int primary key, name varchar(255) not null, number varchar(255) not null); +insert into t1 values (1, 'Gamma', '123'), (2, 'Gamma Ext', '123a'), (3, 'Alpha', '001'), (4, 'Beta', '200c'); +select distinct t1.name as 'Building Name',t1.number as 'Building Number' from t1 order by t1.name asc; +Building Name Building Number +Gamma 123 +Gamma Ext 123a +Alpha 001 +Beta 200c +drop table t1; create table t1 (id int not null,col1 int not null,col2 int not null,index(col1)); insert into t1 values(1,2,2),(2,2,1),(3,1,2),(4,1,1),(5,1,4),(6,2,3),(7,3,1),(8,2,4); select * from t1 order by col1,col2; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 9ae9c1b5e12..465920deaed 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -79,6 +79,16 @@ select distinct i from t1 order by 1-i; select distinct i from t1 order by mod(i,2),i; drop table t1; +# +# bug#3681 +# + +create table t1 ( pk int primary key, name varchar(255) not null, number varchar(255) not null); +insert into t1 values (1, 'Gamma', '123'), (2, 'Gamma Ext', '123a'), (3, 'Alpha', '001'), (4, 'Beta', '200c'); +select distinct t1.name as 'Building Name',t1.number as 'Building Number' from t1 order by t1.name asc; +drop table t1; + + # # Order by on first index part # diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 47ecc57cf16..92bc13cb01e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -665,7 +665,6 @@ JOIN::optimize() if (!order && org_order) skip_sort_order= 1; } - order= remove_const(this, order, conds, &simple_order); if (group_list || tmp_table_param.sum_func_count) { if (! hidden_group_fields) From e18cd2ea9f58f2bc94a5d62af15e1c4380d98924 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Sat, 15 May 2004 17:07:44 +0500 Subject: [PATCH 32/47] Fixes for #3371, #3372, #3374, #3375, #3376 --- libmysql/libmysql.c | 54 +++++++++++++++++++++++------------------ libmysqld/lib_sql.cc | 7 ++++-- sql/sql_parse.cc | 2 +- sql/sql_prepare.cc | 58 ++++++++++++++++++++++++++++++++++++++++++++ tests/client_test.c | 3 +++ 5 files changed, 97 insertions(+), 27 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index a467b7fc9fd..2214ca68c81 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3729,28 +3729,6 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) mysql= mysql->last_used_con; - if (stmt->update_max_length && !stmt->bind_result_done) - { - /* - We must initalize the bind structure to be able to calculate - max_length - */ - MYSQL_BIND *bind, *end; - MYSQL_FIELD *field; - bzero((char*) stmt->bind, sizeof(*stmt->bind)* stmt->field_count); - - for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields; - bind < end ; - bind++, field++) - { - bind->buffer_type= field->type; - bind->buffer_length=1; - } - - mysql_stmt_bind_result(stmt, stmt->bind); - stmt->bind_result_done= 0; /* No normal bind done */ - } - while ((pkt_len= net_safe_read(mysql)) != packet_error) { cp= net->read_pos; @@ -3768,8 +3746,6 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) memcpy((char *) cur->data, (char *) cp+1, pkt_len-1); cur->length= pkt_len; /* To allow us to do sanity checks */ result->rows++; - if (stmt->update_max_length) - stmt_update_metadata(stmt, cur); } else { @@ -3814,6 +3790,29 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) result->rows= 0; stmt->data_cursor= NULL; } + + if (stmt->update_max_length && !stmt->bind_result_done) + { + /* + We must initalize the bind structure to be able to calculate + max_length + */ + MYSQL_BIND *bind, *end; + MYSQL_FIELD *field; + bzero((char*) stmt->bind, sizeof(*stmt->bind)* stmt->field_count); + + for (bind= stmt->bind, end= bind + stmt->field_count, field= stmt->fields; + bind < end ; + bind++, field++) + { + bind->buffer_type= field->type; + bind->buffer_length=1; + } + + mysql_stmt_bind_result(stmt, stmt->bind); + stmt->bind_result_done= 0; /* No normal bind done */ + } + if ((*mysql->methods->read_binary_rows)(stmt)) { free_root(&result->alloc, MYF(MY_KEEP_PREALLOC)); @@ -3822,6 +3821,13 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt) DBUG_RETURN(1); } + if (stmt->update_max_length) + { + MYSQL_ROWS *cur= result->data; + for(; cur; cur=cur->next) + stmt_update_metadata(stmt, cur); + } + stmt->data_cursor= result->data; mysql->affected_rows= stmt->affected_rows= result->rows; stmt->read_row_func= stmt_read_row_buffered; diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index cfb50d3907a..09b03e38f2e 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -197,6 +197,8 @@ static int emb_stmt_execute(MYSQL_STMT *stmt) set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate); DBUG_RETURN(1); } + stmt->affected_rows= stmt->mysql->affected_rows; + stmt->insert_id= stmt->mysql->insert_id; DBUG_RETURN(0); } @@ -605,13 +607,14 @@ bool Protocol::send_fields(List *list, uint flag) if (!(res=item->val_str(&tmp))) { - client_field->def= strdup_root(field_alloc, ""); client_field->def_length= 0; + client_field->def= strmake_root(field_alloc, "",0); } else { - client_field->def= strdup_root(field_alloc, res->ptr()); client_field->def_length= res->length(); + client_field->def= strmake_root(field_alloc, res->ptr(), + client_field->def_length); } } else diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e949d40625d..9a750b2df99 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1493,7 +1493,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->query_rest.length(length); } else - thd->query_rest.copy(length); + thd->query_rest.copy(packet, length, thd->query_rest.charset()); break; #endif /*EMBEDDED_LIBRARY*/ } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 61e5b778b64..68da21018a0 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -309,6 +309,7 @@ void set_param_double(Item_param *param, uchar **pos, ulong len) *pos+= 8; } +#ifndef EMBEDDED_LIBRARY void set_param_time(Item_param *param, uchar **pos, ulong len) { ulong length; @@ -386,6 +387,62 @@ void set_param_date(Item_param *param, uchar **pos, ulong len) *pos+= length; } +#else/*!EMBEDDED_LIBRARY*/ +void set_param_time(Item_param *param, uchar **pos, ulong len) +{ + TIME tm; + MYSQL_TIME *to= (MYSQL_TIME*)*pos; + + tm.second_part= to->second_part; + + tm.day= to->day; + tm.hour= to->hour; + tm.minute= to->minute; + tm.second= to->second; + + tm.year= tm.month= 0; + tm.neg= to->neg; + + param->set_time(&tm, TIMESTAMP_TIME); +} + +void set_param_datetime(Item_param *param, uchar **pos, ulong len) +{ + TIME tm; + MYSQL_TIME *to= (MYSQL_TIME*)*pos; + + tm.second_part= to->second_part; + + tm.day= to->day; + tm.hour= to->hour; + tm.minute= to->minute; + tm.second= to->second; + tm.year= to->year; + tm.month= to->month; + tm.neg= 0; + + param->set_time(&tm, TIMESTAMP_DATETIME); +} + +void set_param_date(Item_param *param, uchar **pos, ulong len) +{ + TIME tm; + MYSQL_TIME *to= (MYSQL_TIME*)*pos; + + tm.second_part= to->second_part; + + tm.day= to->day; + tm.year= to->year; + tm.month= to->month; + tm.neg= 0; + tm.hour= tm.minute= tm.second= 0; + tm.second_part= 0; + tm.neg= 0; + + param->set_time(&tm, TIMESTAMP_DATE); +} +#endif /*!EMBEDDED_LIBRARY*/ + void set_param_str(Item_param *param, uchar **pos, ulong len) { ulong length= get_param_length(pos, len); @@ -568,6 +625,7 @@ static bool emb_insert_params(Prepared_statement *stmt) { Item_param *param= *it; setup_one_conversion_function(param, client_param->buffer_type); + param->unsigned_flag= client_param->is_unsigned; if (!param->long_data_supplied) { if (*client_param->is_null) diff --git a/tests/client_test.c b/tests/client_test.c index ba70bcd7fa7..f859bffb405 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -9872,7 +9872,10 @@ int main(int argc, char **argv) test_stiny_bug(); /* test a simple conv bug from php */ test_field_misc(); /* check the field info for misc case, bug: #74 */ test_set_option(); /* test the SET OPTION feature, bug #85 */ + /*TODO HF: here should be NO_EMBEDDED_ACCESS_CHECKS*/ +#ifndef EMBEDDED_LIBRARY test_prepare_grant(); /* to test the GRANT command, bug #89 */ +#endif test_frm_bug(); /* test the crash when .frm is invalid, bug #93 */ test_explain_bug(); /* test for the EXPLAIN, bug #115 */ test_decimal_bug(); /* test for the decimal bug */ From 08062146206a8e8a058a9628ccd6c66e16f42463 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Sat, 15 May 2004 16:13:08 +0300 Subject: [PATCH 33/47] Optimising UNION ALL (WL 1687) --- sql/sql_union.cc | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 63638b618d9..e6568f5f598 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -339,8 +339,8 @@ int st_select_lex_unit::exec() item->reset(); table->file->delete_all_rows(); } - if (union_distinct) // for subselects - table->file->extra(HA_EXTRA_CHANGE_KEY_TO_UNIQUE); + if (union_distinct && table->file->enable_indexes(HA_KEY_SWITCH_ALL)) + DBUG_RETURN(1); // For sub-selects for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) { ha_rows records_at_start= 0; @@ -392,7 +392,11 @@ int st_select_lex_unit::exec() records_at_start= table->file->records; sl->join->exec(); if (sl == union_distinct) - table->file->extra(HA_EXTRA_CHANGE_KEY_TO_DUP); + { + if (table->file->disable_indexes(HA_KEY_SWITCH_ALL)) + DBUG_RETURN(1); + table->no_keyread=1; + } res= sl->join->error; offset_limit_cnt= sl->offset_limit; if (!res && union_result->flush()) From 314a8bf1148adc35263971a674333c02a8081b93 Mon Sep 17 00:00:00 2001 From: "monty@mishka.local" <> Date: Sun, 16 May 2004 14:48:32 +0300 Subject: [PATCH 34/47] key_cmp -> key_cmp_if_same New records_in_range() interface (similar to read_range()) Macros for faster bitmap handling Simplify read_range() code (#WL1786) New general key_cmp() function to compare keys --- heap/hp_hash.c | 37 ++++++++--------- include/heap.h | 7 +--- include/my_base.h | 10 +++++ include/my_bitmap.h | 6 +++ include/myisam.h | 5 +-- include/myisammrg.h | 5 +-- myisam/mi_range.c | 70 +++++++++++++++++++------------ myisam/mi_test2.c | 22 ++++++++-- myisam/rt_test.c | 79 +++++++++++++---------------------- myisam/sp_test.c | 84 ++++++++++++++------------------------ myisammrg/myrg_range.c | 11 ++--- mysys/my_bitmap.c | 6 +-- sql/examples/ha_example.cc | 11 ++--- sql/field.cc | 9 ++-- sql/ha_berkeley.cc | 29 +++++++------ sql/ha_berkeley.h | 7 +--- sql/ha_heap.cc | 34 ++++++--------- sql/ha_heap.h | 5 +-- sql/ha_innodb.cc | 39 +++++++----------- sql/ha_innodb.h | 6 +-- sql/ha_isam.cc | 23 ++++++----- sql/ha_isam.h | 6 +-- sql/ha_myisam.cc | 26 ++++-------- sql/ha_myisam.h | 6 +-- sql/ha_myisammrg.cc | 16 +++----- sql/ha_myisammrg.h | 6 +-- sql/ha_ndbcluster.cc | 23 +++++------ sql/ha_ndbcluster.h | 7 +--- sql/handler.cc | 66 ++++++++++-------------------- sql/handler.h | 25 ++++-------- sql/key.cc | 76 +++++++++++++++++++++++++++++++++- sql/mysql_priv.h | 5 ++- sql/opt_range.cc | 81 ++++++++++++++---------------------- sql/opt_range.h | 7 +++- sql/opt_sum.cc | 2 +- sql/sql_acl.cc | 4 +- sql/sql_select.cc | 4 +- 37 files changed, 405 insertions(+), 460 deletions(-) diff --git a/heap/hp_hash.c b/heap/hp_hash.c index d040f37aea0..38ed581fe58 100644 --- a/heap/hp_hash.c +++ b/heap/hp_hash.c @@ -29,19 +29,15 @@ hp_rb_records_in_range() info HEAP handler inx Index to use - start_key Start of range. Null pointer if from first key - start_key_len Length of start key - start_search_flag Flag if start key should be included or not - end_key End of range. Null pointer if to last key - end_key_len Length of end key - end_search_flag Flag if start key should be included or not + min_key Min key. Is = 0 if no min range + max_key Max key. Is = 0 if no max range NOTES - start_search_flag can have one of the following values: + min_key.flag can have one of the following values: HA_READ_KEY_EXACT Include the key in the range HA_READ_AFTER_KEY Don't include key in range - end_search_flag can have one of the following values: + max_key.flag can have one of the following values: HA_READ_BEFORE_KEY Don't include key in range HA_READ_AFTER_KEY Include all 'end_key' values in the range @@ -52,11 +48,8 @@ the range. */ -ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, - uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key, uint end_key_len, - enum ha_rkey_function end_search_flag) +ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, key_range *min_key, + key_range *max_key) { ha_rows start_pos, end_pos; HP_KEYDEF *keyinfo= info->s->keydef + inx; @@ -67,12 +60,12 @@ ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, info->lastinx= inx; custom_arg.keyseg= keyinfo->seg; custom_arg.search_flag= SEARCH_FIND | SEARCH_SAME; - if (start_key) + if (min_key) { custom_arg.key_length= hp_rb_pack_key(keyinfo, (uchar*) info->recbuf, - (uchar*) start_key, - start_key_len); - start_pos= tree_record_pos(rb_tree, info->recbuf, start_search_flag, + (uchar*) min_key->key, + min_key->length); + start_pos= tree_record_pos(rb_tree, info->recbuf, min_key->flag, &custom_arg); } else @@ -80,11 +73,12 @@ ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, start_pos= 0; } - if (end_key) + if (max_key) { custom_arg.key_length= hp_rb_pack_key(keyinfo, (uchar*) info->recbuf, - (uchar*) end_key, end_key_len); - end_pos= tree_record_pos(rb_tree, info->recbuf, end_search_flag, + (uchar*) max_key->key, + max_key->length); + end_pos= tree_record_pos(rb_tree, info->recbuf, max_key->flag, &custom_arg); } else @@ -100,12 +94,13 @@ ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, (end_pos == start_pos ? (ha_rows) 1 : end_pos - start_pos)); } + /* Search after a record based on a key */ /* Sets info->current_ptr to found record */ /* next_flag: Search=0, next=1, prev =2, same =3 */ byte *hp_search(HP_INFO *info, HP_KEYDEF *keyinfo, const byte *key, - uint nextflag) + uint nextflag) { reg1 HASH_INFO *pos,*prev_ptr; int flag; diff --git a/include/heap.h b/include/heap.h index b536937c8c0..63f2abbabc7 100644 --- a/include/heap.h +++ b/include/heap.h @@ -182,11 +182,8 @@ extern int heap_disable_indexes(HP_INFO *info); extern int heap_enable_indexes(HP_INFO *info); extern int heap_indexes_are_disabled(HP_INFO *info); extern void heap_update_auto_increment(HP_INFO *info, const byte *record); -ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, const byte *start_key, - uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key, uint end_key_len, - enum ha_rkey_function end_search_flag); +ha_rows hp_rb_records_in_range(HP_INFO *info, int inx, key_range *min_key, + key_range *max_key); int heap_rkey(HP_INFO *info, byte *record, int inx, const byte *key, uint key_len, enum ha_rkey_function find_flag); extern gptr heap_find(HP_INFO *info,int inx,const byte *key); diff --git a/include/my_base.h b/include/my_base.h index 4a2f3f85083..f912cb4278c 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -349,6 +349,16 @@ enum data_file_type { STATIC_RECORD,DYNAMIC_RECORD,COMPRESSED_RECORD }; +/* For key ranges */ + +typedef struct st_key_range +{ + const byte *key; + uint length; + enum ha_rkey_function flag; +} key_range; + + /* For number of records */ #ifdef BIG_TABLES #define rows2double(A) ulonglong2double(A) diff --git a/include/my_bitmap.h b/include/my_bitmap.h index 5b3da011f54..a4511bf3414 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -55,6 +55,12 @@ extern void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit); extern void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size); extern void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2); extern void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2); + +/* Fast, not thread safe, bitmap functions */ +#define bitmap_fast_set_bit(MAP, BIT) (MAP)->bitmap[(BIT) / 8] |= (1 << ((BIT) & 7)) +#define bitmap_fast_clear_bit(MAP, BIT) (MAP)->bitmap[(BIT) / 8] &= ~ (1 << ((BIT) & 7)) +#define bitmap_fast_is_set(MAP, BIT) (MAP)->bitmap[(BIT) / 8] & (1 << ((BIT) & 7)) + #ifdef __cplusplus } #endif diff --git a/include/myisam.h b/include/myisam.h index 93e2dc15574..c99e9a30b08 100644 --- a/include/myisam.h +++ b/include/myisam.h @@ -231,10 +231,7 @@ extern int mi_extra(struct st_myisam_info *file, enum ha_extra_function function, void *extra_arg); extern ha_rows mi_records_in_range(struct st_myisam_info *info,int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + key_range *min_key, key_range *max_key); extern int mi_log(int activate_log); extern int mi_is_changed(struct st_myisam_info *info); extern int mi_delete_all_rows(struct st_myisam_info *info); diff --git a/include/myisammrg.h b/include/myisammrg.h index 8b09e1a9231..de8a36c2d0a 100644 --- a/include/myisammrg.h +++ b/include/myisammrg.h @@ -101,10 +101,7 @@ extern int myrg_extra(MYRG_INFO *file,enum ha_extra_function function, void *extra_arg); extern void myrg_extrafunc(MYRG_INFO *info,invalidator_by_filename inv); extern ha_rows myrg_records_in_range(MYRG_INFO *info,int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + key_range *min_key, key_range *max_key); extern ulonglong myrg_position(MYRG_INFO *info); #ifdef __cplusplus diff --git a/myisam/mi_range.c b/myisam/mi_range.c index caa57ce6187..db01ada16dd 100644 --- a/myisam/mi_range.c +++ b/myisam/mi_range.c @@ -30,15 +30,27 @@ static uint _mi_keynr(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *page, uchar *keypos,uint *ret_max_key); - /* If start_key = 0 assume read from start */ - /* If end_key = 0 assume read to end */ - /* Returns HA_POS_ERROR on error */ +/* + Estimate how many records there is in a given range -ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key, - uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key, uint end_key_len, - enum ha_rkey_function end_search_flag) + SYNOPSIS + mi_records_in_range() + info MyISAM handler + inx Index to use + min_key Min key. Is = 0 if no min range + max_key Max key. Is = 0 if no max range + + NOTES + We should ONLY return 0 if there is no rows in range + + RETURN + HA_POS_ERROR error (or we can't estimate number of rows) + number Estimated number of rows +*/ + + +ha_rows mi_records_in_range(MI_INFO *info, int inx, key_range *min_key, + key_range *max_key) { ha_rows start_pos,end_pos,res; DBUG_ENTER("mi_records_in_range"); @@ -54,27 +66,31 @@ ha_rows mi_records_in_range(MI_INFO *info, int inx, const byte *start_key, switch(info->s->keyinfo[inx].key_alg){ case HA_KEY_ALG_RTREE: - { - uchar * key_buff; - if (start_key_len == 0) - start_key_len=USE_WHOLE_KEY; - key_buff=info->lastkey+info->s->base.max_key_length; - start_key_len= _mi_pack_key(info,inx,key_buff,(uchar*) start_key, - start_key_len, (HA_KEYSEG**) 0); - res=rtree_estimate(info, inx, key_buff, start_key_len, myisam_read_vec[start_search_flag]); - res=res?res:1; - break; - } + { + uchar * key_buff; + uint start_key_len; + + key_buff= info->lastkey+info->s->base.max_key_length; + start_key_len= _mi_pack_key(info,inx, key_buff, + (uchar*) min_key->key, min_key->length, + (HA_KEYSEG**) 0); + res= rtree_estimate(info, inx, key_buff, start_key_len, + myisam_read_vec[min_key->flag]); + res= res ? res : 1; /* Don't return 0 */ + break; + } case HA_KEY_ALG_BTREE: default: - start_pos= (start_key ? - _mi_record_pos(info,start_key,start_key_len,start_search_flag) : - (ha_rows) 0); - end_pos= (end_key ? - _mi_record_pos(info,end_key,end_key_len,end_search_flag) : - info->state->records+ (ha_rows) 1); - res=end_pos < start_pos ? (ha_rows) 0 : - (end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos); + start_pos= (min_key ? + _mi_record_pos(info, min_key->key, min_key->length, + min_key->flag) : + (ha_rows) 0); + end_pos= (max_key ? + _mi_record_pos(info, max_key->key, max_key->length, + max_key->flag) : + info->state->records+ (ha_rows) 1); + res= (end_pos < start_pos ? (ha_rows) 0 : + (end_pos == start_pos ? (ha_rows) 1 : end_pos-start_pos)); if (start_pos == HA_POS_ERROR || end_pos == HA_POS_ERROR) res=HA_POS_ERROR; } diff --git a/myisam/mi_test2.c b/myisam/mi_test2.c index d3c3cc2c492..56d8357536a 100644 --- a/myisam/mi_test2.c +++ b/myisam/mi_test2.c @@ -606,13 +606,20 @@ int main(int argc, char *argv[]) mi_status(file,&info,HA_STATUS_VARIABLE); for (i=0 ; i < info.keys ; i++) { + key_range min_key, max_key; if (mi_rfirst(file,read_record,(int) i) || mi_rlast(file,read_record2,(int) i)) goto err; copy_key(file,(uint) i,(uchar*) read_record,(uchar*) key); copy_key(file,(uint) i,(uchar*) read_record2,(uchar*) key2); - range_records=mi_records_in_range(file,(int) i,key,0,HA_READ_KEY_EXACT, - key2,0,HA_READ_AFTER_KEY); + min_key.key= key; + min_key.length= USE_WHOLE_KEY; + min_key.flag= HA_READ_KEY_EXACT; + max_key.key= key2; + max_key.length= USE_WHOLE_KEY; + max_key.flag= HA_READ_AFTER_KEY; + + range_records= mi_records_in_range(file,(int) i, &min_key, &max_key); if (range_records < info.records*8/10 || range_records > info.records*12/10) { @@ -634,12 +641,19 @@ int main(int argc, char *argv[]) for (k=rnd(1000)+1 ; k>0 && key1[k] == 0 ; k--) ; if (j != 0 && k != 0) { + key_range min_key, max_key; if (j > k) swap(int,j,k); sprintf(key,"%6d",j); sprintf(key2,"%6d",k); - range_records=mi_records_in_range(file,0,key,0,HA_READ_AFTER_KEY, - key2,0,HA_READ_BEFORE_KEY); + + min_key.key= key; + min_key.length= USE_WHOLE_KEY; + min_key.flag= HA_READ_AFTER_KEY; + max_key.key= key2; + max_key.length= USE_WHOLE_KEY; + max_key.flag= HA_READ_BEFORE_KEY; + range_records= mi_records_in_range(file, 0, &min_key, &max_key); records=0; for (j++ ; j < k ; j++) records+=key1[j]; diff --git a/myisam/rt_test.c b/myisam/rt_test.c index bbeb8fce2d1..c1126c1939a 100644 --- a/myisam/rt_test.c +++ b/myisam/rt_test.c @@ -39,7 +39,6 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) } - int run_test(const char *filename) { MI_INFO *file; @@ -48,6 +47,7 @@ int run_test(const char *filename) MI_COLUMNDEF recinfo[20]; MI_KEYDEF keyinfo[20]; HA_KEYSEG keyseg[20]; + key_range range; int silent=0; int opt_unique=0; @@ -66,15 +66,12 @@ int run_test(const char *filename) int upd= 10; ha_rows hrows; - - /* Define a column for NULLs and DEL markers*/ recinfo[0].type=FIELD_NORMAL; recinfo[0].length=1; /* For NULL bits */ rec_length=1; - /* Define 2*ndims columns for coordinates*/ for (i=1; i<=2*ndims ;i++){ @@ -83,7 +80,6 @@ int run_test(const char *filename) rec_length+=key_length; } - /* Define a key with 2*ndims segments */ keyinfo[0].seg=keyseg; @@ -101,8 +97,7 @@ int run_test(const char *filename) keyinfo[0].seg[i].language=default_charset_info->number; } - - if(!silent) + if (!silent) printf("- Creating isam-file\n"); bzero((char*) &create_info,sizeof(create_info)); @@ -115,15 +110,11 @@ int run_test(const char *filename) recinfo,uniques,&uniquedef,&create_info,create_flag)) goto err; - - - - if(!silent) + if (!silent) printf("- Open isam-file\n"); if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) goto err; - if (!silent) printf("- Writing key:s\n"); @@ -144,11 +135,9 @@ int run_test(const char *filename) } } - - if((error=read_with_pos(file,silent))) + if ((error=read_with_pos(file,silent))) goto err; - if (!silent) printf("- Reading rows with key\n"); @@ -160,12 +149,12 @@ int run_test(const char *filename) bzero((char*) read_record,MAX_REC_LENGTH); error=mi_rkey(file,read_record,0,record+1,0,HA_READ_MBR_EQUAL); - if(error && error!=HA_ERR_KEY_NOT_FOUND) + if (error && error!=HA_ERR_KEY_NOT_FOUND) { printf(" mi_rkey: %3d errno: %3d\n",error,my_errno); goto err; } - if(error == HA_ERR_KEY_NOT_FOUND) + if (error == HA_ERR_KEY_NOT_FOUND) { print_record(record,mi_position(file)," NOT FOUND\n"); continue; @@ -173,10 +162,6 @@ int run_test(const char *filename) print_record(read_record,mi_position(file),"\n"); } - - - - if (!silent) printf("- Deleting rows\n"); for (i=0; i < nrecords/4; i++) @@ -184,7 +169,7 @@ int run_test(const char *filename) my_errno=0; bzero((char*) read_record,MAX_REC_LENGTH); error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR); - if(error) + if (error) { printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno); goto err; @@ -192,14 +177,13 @@ int run_test(const char *filename) print_record(read_record,mi_position(file),"\n"); error=mi_delete(file,read_record); - if(error) + if (error) { printf("pos: %2d mi_delete: %3d errno: %3d\n",i,error,my_errno); goto err; } } - if (!silent) printf("- Updating rows with position\n"); for (i=0; i < (nrecords - nrecords/4) ; i++) @@ -207,9 +191,9 @@ int run_test(const char *filename) my_errno=0; bzero((char*) read_record,MAX_REC_LENGTH); error=mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR); - if(error) + if (error) { - if(error==HA_ERR_RECORD_DELETED) + if (error==HA_ERR_RECORD_DELETED) continue; printf("pos: %2d mi_rrnd: %3d errno: %3d\n",i,error,my_errno); goto err; @@ -219,19 +203,16 @@ int run_test(const char *filename) printf("\t-> "); print_record(record,mi_position(file),"\n"); error=mi_update(file,read_record,record); - if(error) + if (error) { printf("pos: %2d mi_update: %3d errno: %3d\n",i,error,my_errno); goto err; } } - - if((error=read_with_pos(file,silent))) + if ((error=read_with_pos(file,silent))) goto err; - - if (!silent) printf("- Test mi_rkey then a sequence of mi_rnext_same\n"); @@ -246,25 +227,20 @@ int run_test(const char *filename) print_record(read_record,mi_position(file)," mi_rkey\n"); row_count=1; - - do { - if((error=mi_rnext_same(file,read_record))) + for (;;) + { + if ((error=mi_rnext_same(file,read_record))) { - if(error==HA_ERR_END_OF_FILE) + if (error==HA_ERR_END_OF_FILE) break; printf("mi_next: %3d errno: %3d\n",error,my_errno); goto err; } print_record(read_record,mi_position(file)," mi_rnext_same\n"); row_count++; - }while(1); + } printf(" %d rows\n",row_count); - - - - - if (!silent) printf("- Test mi_rfirst then a sequence of mi_rnext\n"); @@ -277,10 +253,11 @@ int run_test(const char *filename) row_count=1; print_record(read_record,mi_position(file)," mi_frirst\n"); - for(i=0;i "); print_record(record,mi_position(file),"\n"); error=mi_update(file,read_record,record); - if(error) + if (error) { printf("pos: %2d mi_update: %3d errno: %3d\n",i,error,my_errno); goto err; } } - - - if((error=read_with_pos(file,silent))) + if ((error=read_with_pos(file,silent))) goto err; - - if (!silent) printf("- Test mi_rkey then a sequence of mi_rnext_same\n"); @@ -219,25 +204,20 @@ int run_test(const char *filename) print_record(read_record,mi_position(file)," mi_rkey\n"); row_count=1; - - do { - if((error=mi_rnext_same(file,read_record))) + for (;;) + { + if ((error=mi_rnext_same(file,read_record))) { - if(error==HA_ERR_END_OF_FILE) + if (error==HA_ERR_END_OF_FILE) break; printf("mi_next: %3d errno: %3d\n",error,my_errno); goto err; } print_record(read_record,mi_position(file)," mi_rnext_same\n"); row_count++; - }while(1); + } printf(" %d rows\n",row_count); - - - - - if (!silent) printf("- Test mi_rfirst then a sequence of mi_rnext\n"); @@ -251,9 +231,9 @@ int run_test(const char *filename) print_record(read_record,mi_position(file)," mi_frirst\n"); for(i=0;i "); @@ -360,7 +339,6 @@ static void print_record(char * record, my_off_t offs,const char * tail) } - #ifdef NOT_USED static void create_point(char *record,uint rownr) { @@ -447,7 +425,6 @@ static void print_key(const char *key,const char * tail) } - #ifdef NOT_USED static int rtree_CreatePointWKB(double *ords, uint n_dims, uchar *wkb) @@ -489,6 +466,7 @@ static int rtree_CreateLineStringWKB(double *ords, uint n_dims, uint n_points, return 9 + n_points * n_dims * 8; } + static void rtree_PrintWKB(uchar *wkb, uint n_dims) { uint wkb_type; diff --git a/myisammrg/myrg_range.c b/myisammrg/myrg_range.c index 7644ae40c7b..aafdf70525c 100644 --- a/myisammrg/myrg_range.c +++ b/myisammrg/myrg_range.c @@ -16,20 +16,15 @@ #include "myrg_def.h" -ha_rows myrg_records_in_range(MYRG_INFO *info, int inx, const byte *start_key, - uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key, uint end_key_len, - enum ha_rkey_function end_search_flag) +ha_rows myrg_records_in_range(MYRG_INFO *info, int inx, + key_range *min_key, key_range *max_key) { ha_rows records=0, res; MYRG_TABLE *table; for (table=info->open_tables ; table != info->end_table ; table++) { - res=mi_records_in_range(table->table, inx, - start_key, start_key_len, start_search_flag, - end_key, end_key_len, end_search_flag); + res= mi_records_in_range(table->table, inx, min_key, max_key); if (res == HA_POS_ERROR) return HA_POS_ERROR; if (records > HA_POS_ERROR - res) diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index da16457c299..0f8984e6b3d 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -104,7 +104,7 @@ void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit) { DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); bitmap_lock(map); - map->bitmap[bitmap_bit / 8] |= (1 << (bitmap_bit & 7)); + bitmap_fast_set_bit(map, bitmap_bit); bitmap_unlock(map); } @@ -144,7 +144,7 @@ void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit) { DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); bitmap_lock(map); - map->bitmap[bitmap_bit / 8] &= ~ (1 << (bitmap_bit & 7)); + bitmap_fast_clear_bit(map, bitmap_bit); bitmap_unlock(map); } @@ -220,7 +220,7 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map) my_bool bitmap_is_set(const MY_BITMAP *map, uint bitmap_bit) { DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8); - return map->bitmap[bitmap_bit / 8] & (1 << (bitmap_bit & 7)); + return bitmap_fast_is_set(map, bitmap_bit); } diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc index b8ae5967475..2d17caf1a83 100644 --- a/sql/examples/ha_example.cc +++ b/sql/examples/ha_example.cc @@ -625,14 +625,11 @@ int ha_example::rename_table(const char * from, const char * to) Called from opt_range.cc by check_quick_keys(). */ -ha_rows ha_example::records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag) +ha_rows ha_example::records_in_range(uint inx, key_range *min_key, + key_range *max_key) { - DBUG_ENTER("ha_example::records_in_range "); - DBUG_RETURN(records); + DBUG_ENTER("ha_example::records_in_range"); + DBUG_RETURN(10); // low number to force index usage } diff --git a/sql/field.cc b/sql/field.cc index edaa29dbaa0..1ad7e039363 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4252,12 +4252,13 @@ int Field_string::cmp(const char *a_ptr, const char *b_ptr) like in latin_de 'ae' and 0xe4 */ return field_charset->coll->strnncollsp(field_charset, - (const uchar*) a_ptr, field_length, - (const uchar*) b_ptr, field_length); + (const uchar*) a_ptr, field_length, + (const uchar*) b_ptr, + field_length); } return field_charset->coll->strnncoll(field_charset, - (const uchar*) a_ptr, field_length, - (const uchar*) b_ptr, field_length); + (const uchar*) a_ptr, field_length, + (const uchar*) b_ptr, field_length); } void Field_string::sort_string(char *to,uint length) diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 593b9575fb6..4dde893116f 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -1542,7 +1542,7 @@ int ha_berkeley::index_next_same(byte * buf, const byte *key, uint keylen) { error=read_row(cursor->c_get(cursor, &last_key, &row, DB_NEXT), (char*) buf, active_index, &row, &last_key, 1); - if (!error && ::key_cmp(table, key, active_index, keylen)) + if (!error && ::key_cmp_if_same(table, key, active_index, keylen)) error=HA_ERR_END_OF_FILE; } DBUG_RETURN(error); @@ -1987,11 +1987,8 @@ double ha_berkeley::scan_time() return rows2double(records/3); } -ha_rows ha_berkeley::records_in_range(int keynr, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag) +ha_rows ha_berkeley::records_in_range(uint keynr, key_range *start_key, + key_range *end_key) { DBT key; DB_KEY_RANGE start_range, end_range; @@ -2000,25 +1997,27 @@ ha_rows ha_berkeley::records_in_range(int keynr, DBUG_ENTER("records_in_range"); if ((start_key && kfile->key_range(kfile,transaction, - pack_key(&key, keynr, key_buff, start_key, - start_key_len), - &start_range,0)) || + pack_key(&key, keynr, key_buff, + start_key->key, + start_key->length), + &start_range,0)) || (end_key && kfile->key_range(kfile,transaction, - pack_key(&key, keynr, key_buff, end_key, - end_key_len), + pack_key(&key, keynr, key_buff, + end_key->key, + end_key->length), &end_range,0))) DBUG_RETURN(HA_BERKELEY_RANGE_COUNT); // Better than returning an error /* purecov: inspected */ if (!start_key) - start_pos=0.0; - else if (start_search_flag == HA_READ_KEY_EXACT) + start_pos= 0.0; + else if (start_key->flag == HA_READ_KEY_EXACT) start_pos=start_range.less; else start_pos=start_range.less+start_range.equal; if (!end_key) - end_pos=1.0; - else if (end_search_flag == HA_READ_BEFORE_KEY) + end_pos= 1.0; + else if (end_key->flag == HA_READ_BEFORE_KEY) end_pos=end_range.less; else end_pos=end_range.less+end_range.equal; diff --git a/sql/ha_berkeley.h b/sql/ha_berkeley.h index 88af2326eac..4bc8e3a5777 100644 --- a/sql/ha_berkeley.h +++ b/sql/ha_berkeley.h @@ -143,12 +143,7 @@ class ha_berkeley: public handler int optimize(THD* thd, HA_CHECK_OPT* check_opt); int check(THD* thd, HA_CHECK_OPT* check_opt); - ha_rows records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); - + ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); int create(const char *name, register TABLE *form, HA_CREATE_INFO *create_info); int delete_table(const char *name); diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 12b922e6fc0..9915dc90dc1 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -363,28 +363,20 @@ int ha_heap::rename_table(const char * from, const char * to) return heap_rename(from,to); } -ha_rows ha_heap::records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag) + +ha_rows ha_heap::records_in_range(uint inx, key_range *min_key, + key_range *max_key) { - KEY *pos=table->key_info+inx; - if (pos->algorithm == HA_KEY_ALG_BTREE) - { - return hp_rb_records_in_range(file, inx, start_key, start_key_len, - start_search_flag, end_key, end_key_len, - end_search_flag); - } - else - { - if (start_key_len != end_key_len || - start_key_len != pos->key_length || - start_search_flag != HA_READ_KEY_EXACT || - end_search_flag != HA_READ_AFTER_KEY) - return HA_POS_ERROR; // Can't only use exact keys - return 10; // Good guess - } + KEY *key=table->key_info+inx; + if (key->algorithm == HA_KEY_ALG_BTREE) + return hp_rb_records_in_range(file, inx, min_key, max_key); + + if (min_key->length != max_key->length || + min_key->length != key->key_length || + min_key->flag != HA_READ_KEY_EXACT || + max_key->flag != HA_READ_AFTER_KEY) + return HA_POS_ERROR; // Can't only use exact keys + return 10; // Good guess } diff --git a/sql/ha_heap.h b/sql/ha_heap.h index 2f849d2574b..f55eda91149 100644 --- a/sql/ha_heap.h +++ b/sql/ha_heap.h @@ -86,10 +86,7 @@ class ha_heap: public handler int disable_indexes(uint mode); int enable_indexes(uint mode); int indexes_are_disabled(void); - ha_rows records_in_range(int inx, const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); int delete_table(const char *from); int rename_table(const char * from, const char * to); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 201ec8f183f..ff491a95043 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3925,18 +3925,11 @@ ha_innobase::records_in_range( /*==========================*/ /* out: estimated number of rows */ - int keynr, /* in: index number */ - const mysql_byte* start_key, /* in: start key value of the - range, may also be empty */ - uint start_key_len, /* in: start key val len, may - also be 0 */ - enum ha_rkey_function start_search_flag,/* in: start search condition - e.g., 'greater than' */ - const mysql_byte* end_key, /* in: range end key val, may - also be empty */ - uint end_key_len, /* in: range end key val len, - may also be 0 */ - enum ha_rkey_function end_search_flag)/* in: range end search cond */ + uint keynr, /* in: index number */ + key_range *min_key, /* in: start key value of the + range, may also be 0 */ + key_range *max_key) /* in: range end key val, may + also be 0 */ { row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; KEY* key; @@ -3957,12 +3950,6 @@ ha_innobase::records_in_range( DBUG_ENTER("records_in_range"); - /* We do not know if MySQL can call this function before calling - external_lock(). To be safe, update the thd of the current table - handle. */ - - update_thd(current_thd); - prebuilt->trx->op_info = (char*)"estimating records in index range"; /* In case MySQL calls this in the middle of a SELECT query, release @@ -3986,17 +3973,21 @@ ha_innobase::records_in_range( range_start, (byte*) key_val_buff, (ulint)upd_and_key_val_buff_len, index, - (byte*) start_key, - (ulint) start_key_len); + (byte*) (min_key ? min_key->key : + (const mysql_byte*) 0), + (ulint) (min_key ? min_key->length : 0)); row_sel_convert_mysql_key_to_innobase( range_end, (byte*) key_val_buff2, buff2_len, index, - (byte*) end_key, - (ulint) end_key_len); + (byte*) (max_key ? max_key->key : + (const mysql_byte*) 0), + (ulint) (max_key ? max_key->length : 0)); - mode1 = convert_search_mode_to_innobase(start_search_flag); - mode2 = convert_search_mode_to_innobase(end_search_flag); + mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag : + HA_READ_KEY_EXACT); + mode2 = convert_search_mode_to_innobase(max_key ? max_key->flag : + HA_READ_KEY_EXACT); n_rows = btr_estimate_n_rows_in_range(index, range_start, mode1, range_end, mode2); diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 83a3edc4126..c585fd9c463 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -166,11 +166,7 @@ class ha_innobase: public handler int start_stmt(THD *thd); void position(byte *record); - ha_rows records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); ha_rows estimate_number_of_rows(); int create(const char *name, register TABLE *form, diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index 09c2aeceafc..85ab25a31d9 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -382,18 +382,21 @@ int ha_isam::create(const char *name, register TABLE *form, } +static key_range no_range= { (byte*) 0, 0, HA_READ_KEY_EXACT }; -ha_rows ha_isam::records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag) +ha_rows ha_isam::records_in_range(uint inx, key_range *min_key, + key_range *max_key) { + /* ISAM checks if 'key' pointer <> 0 to know if there is no range */ + if (!min_key) + min_key= &no_range; + if (!max_key) + max_key= &no_range; return (ha_rows) nisam_records_in_range(file, - inx, - start_key,start_key_len, - start_search_flag, - end_key,end_key_len, - end_search_flag); + (int) inx, + min_key->key, min_key->length, + min_key->flag, + max_key->key, max_key->length, + max_key->flag); } #endif /* HAVE_ISAM */ diff --git a/sql/ha_isam.h b/sql/ha_isam.h index 2c8ec274145..8a887ababde 100644 --- a/sql/ha_isam.h +++ b/sql/ha_isam.h @@ -70,11 +70,7 @@ class ha_isam: public handler void info(uint); int extra(enum ha_extra_function operation); int external_lock(THD *thd, int lock_type); - ha_rows records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 1b24633953d..feac5c51dce 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1515,19 +1515,15 @@ longlong ha_myisam::get_auto_increment() SYNOPSIS records_in_range() inx Index to use - start_key Start of range. Null pointer if from first key - start_key_len Length of start key - start_search_flag Flag if start key should be included or not - end_key End of range. Null pointer if to last key - end_key_len Length of end key - end_search_flag Flag if start key should be included or not + min_key Start of range. Null pointer if from first key + max_key End of range. Null pointer if to last key NOTES - start_search_flag can have one of the following values: + min_key.flag can have one of the following values: HA_READ_KEY_EXACT Include the key in the range HA_READ_AFTER_KEY Don't include key in range - end_search_flag can have one of the following values: + max_key.flag can have one of the following values: HA_READ_BEFORE_KEY Don't include key in range HA_READ_AFTER_KEY Include all 'end_key' values in the range @@ -1538,18 +1534,10 @@ longlong ha_myisam::get_auto_increment() the range. */ -ha_rows ha_myisam::records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag) +ha_rows ha_myisam::records_in_range(uint inx, key_range *min_key, + key_range *max_key) { - return (ha_rows) mi_records_in_range(file, - inx, - start_key,start_key_len, - start_search_flag, - end_key,end_key_len, - end_search_flag); + return (ha_rows) mi_records_in_range(file, (int) inx, min_key, max_key); } diff --git a/sql/ha_myisam.h b/sql/ha_myisam.h index 206a1c62a2f..77887220903 100644 --- a/sql/ha_myisam.h +++ b/sql/ha_myisam.h @@ -110,11 +110,7 @@ class ha_myisam: public handler int indexes_are_disabled(void); void start_bulk_insert(ha_rows rows); int end_bulk_insert(); - ha_rows records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); void update_create_info(HA_CREATE_INFO *create_info); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 041d9eaead3..9aa6d039efb 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -199,20 +199,14 @@ void ha_myisammrg::position(const byte *record) ha_store_ptr(ref, ref_length, (my_off_t) position); } -ha_rows ha_myisammrg::records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag) + +ha_rows ha_myisammrg::records_in_range(uint inx, key_range *min_key, + key_range *max_key) { - return (ha_rows) myrg_records_in_range(file, - inx, - start_key,start_key_len, - start_search_flag, - end_key,end_key_len, - end_search_flag); + return (ha_rows) myrg_records_in_range(file, (int) inx, min_key, max_key); } + void ha_myisammrg::info(uint flag) { MYMERGE_INFO info; diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index c0f81a77a1e..fd36c78202d 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -70,11 +70,7 @@ class ha_myisammrg: public handler int rnd_next(byte *buf); int rnd_pos(byte * buf, byte *pos); void position(const byte *record); - ha_rows records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); my_off_t row_position() { return myrg_position(file); } void info(uint); int extra(enum ha_extra_function operation); diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 3bc322878d1..21056ef4a8f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2748,22 +2748,19 @@ void ha_ndbcluster::set_dbname(const char *path_name) ha_rows -ha_ndbcluster::records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag) +ha_ndbcluster::records_in_range(uint inx, key_range *min_key, + key_range *max_key) { - ha_rows records= 10; - KEY* key_info= table->key_info + inx; + ha_rows records= 10; /* Good guess when you don't know anything */ + KEY *key_info= table->key_info + inx; uint key_length= key_info->key_length; DBUG_ENTER("records_in_range"); - DBUG_PRINT("enter", ("inx: %d", inx)); - DBUG_PRINT("enter", ("start_key: %x, start_key_len: %d", start_key, start_key_len)); - DBUG_PRINT("enter", ("start_search_flag: %d", start_search_flag)); - DBUG_PRINT("enter", ("end_key: %x, end_key_len: %d", end_key, end_key_len)); - DBUG_PRINT("enter", ("end_search_flag: %d", end_search_flag)); + DBUG_PRINT("enter", ("inx: %u", inx)); + DBUG_DUMP("start_key", min_key->key, min_key->length); + DBUG_DUMP("end_key", max_key->key, max_key->length); + DBUG_PRINT("enter", ("start_search_flag: %u end_search_flag: %u", + min_key->flag, max_key->flag)); /* Check that start_key_len is equal to @@ -2772,7 +2769,7 @@ ha_ndbcluster::records_in_range(int inx, */ NDB_INDEX_TYPE idx_type= get_index_type(inx); if ((idx_type == UNIQUE_INDEX || idx_type == PRIMARY_KEY_INDEX) && - start_key_len < key_length) + min_key->length < key_length) { DBUG_PRINT("warning", ("Tried to use index which required" "full key length: %d, HA_POS_ERROR", diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index bd601f39fc4..029ebc11e46 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -121,12 +121,7 @@ class ha_ndbcluster: public handler } double scan_time(); - ha_rows records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); - + ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); static Ndb* seize_ndb(); static void release_ndb(Ndb* ndb); diff --git a/sql/handler.cc b/sql/handler.cc index 7374242ebf8..f8eca1b93ef 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1184,7 +1184,7 @@ int handler::index_next_same(byte *buf, const byte *key, uint keylen) int error; if (!(error=index_next(buf))) { - if (key_cmp(table, key, active_index, keylen)) + if (key_cmp_if_same(table, key, active_index, keylen)) { table->status=STATUS_NOT_FOUND; error=HA_ERR_END_OF_FILE; @@ -1388,6 +1388,7 @@ int ha_discover(const char* dbname, const char* name, read_range_first() start_key Start key. Is 0 if no min range end_key End key. Is 0 if no max range + eq_range_arg Set to 1 if start_key == end_key sorted Set to 1 if result should be sorted per key NOTES @@ -1401,11 +1402,12 @@ int ha_discover(const char* dbname, const char* name, int handler::read_range_first(const key_range *start_key, const key_range *end_key, - bool sorted) + bool eq_range_arg, bool sorted) { int result; DBUG_ENTER("handler::read_range_first"); + eq_range= eq_range_arg; end_range= 0; if (end_key) { @@ -1416,7 +1418,6 @@ int handler::read_range_first(const key_range *start_key, } range_key_part= table->key_info[active_index].key_part; - if (!start_key) // Read first record result= index_first(table->record[0]); else @@ -1438,7 +1439,6 @@ int handler::read_range_first(const key_range *start_key, SYNOPSIS read_range_next() - eq_range Set to 1 if start_key == end_key NOTES Record is read into table->record[0] @@ -1449,17 +1449,19 @@ int handler::read_range_first(const key_range *start_key, # Error code */ -int handler::read_range_next(bool eq_range) +int handler::read_range_next() { int result; DBUG_ENTER("handler::read_range_next"); if (eq_range) - result= index_next_same(table->record[0], - end_range->key, - end_range->length); - else - result= index_next(table->record[0]); + { + /* We trust that index_next_same always gives a row in range */ + DBUG_RETURN(index_next_same(table->record[0], + end_range->key, + end_range->length)); + } + result= index_next(table->record[0]); if (result) DBUG_RETURN(result); DBUG_RETURN(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE); @@ -1467,16 +1469,18 @@ int handler::read_range_next(bool eq_range) /* - Compare if found key is over max-value + Compare if found key (in row) is over max-value SYNOPSIS compare_key - range key to compare to row + range range to compare to row. May be 0 for no range NOTES - For this to work, the row must be stored in table->record[0] + See key.cc::key_cmp() for details RETURN + The return value is SIGN(key_in_row - range_key): + 0 Key is equal to range or 'range' == 0 (no range) -1 Key is less than range 1 Key is larger than range @@ -1484,37 +1488,11 @@ int handler::read_range_next(bool eq_range) int handler::compare_key(key_range *range) { - KEY_PART_INFO *key_part= range_key_part; - uint store_length; - + int cmp; if (!range) return 0; // No max range - - for (const char *key= (const char*) range->key, *end=key+range->length; - key < end; - key+= store_length, key_part++) - { - int cmp; - store_length= key_part->store_length; - if (key_part->null_bit) - { - if (*key) - { - if (!key_part->field->is_null()) - return 1; - continue; - } - else if (key_part->field->is_null()) - return 0; - key++; // Skip null byte - store_length--; - } - if ((cmp=key_part->field->key_cmp((byte*) key, key_part->length)) < 0) - return -1; - if (cmp > 0) - return 1; - } - return key_compare_result_on_equal; + cmp= key_cmp(range_key_part, range->key, range->length); + if (!cmp) + cmp= key_compare_result_on_equal; + return cmp; } - - diff --git a/sql/handler.h b/sql/handler.h index 4f721a01412..bbeefa7c916 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -234,14 +234,6 @@ typedef struct st_ha_check_opt } HA_CHECK_OPT; -typedef struct st_key_range -{ - const byte *key; - uint length; - enum ha_rkey_function flag; -} key_range; - - class handler :public Sql_alloc { protected: @@ -268,6 +260,7 @@ public: key_range save_end_range, *end_range; KEY_PART_INFO *range_key_part; int key_compare_result_on_equal; + bool eq_range; uint errkey; /* Last dup key */ uint sortkey, key_used_on_scan; @@ -330,13 +323,14 @@ public: return (my_errno=HA_ERR_WRONG_COMMAND); } virtual int read_range_first(const key_range *start_key, - const key_range *end_key, - bool sorted); - virtual int read_range_next(bool eq_range); + const key_range *end_key, + bool eq_range, bool sorted); + virtual int read_range_next(); int compare_key(key_range *range); virtual int ft_init() { return -1; } - virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key, uint keylen) + virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key, + uint keylen) { return NULL; } virtual int ft_read(byte *buf) { return -1; } virtual int rnd_init(bool scan=1)=0; @@ -345,11 +339,8 @@ public: virtual int rnd_pos(byte * buf, byte *pos)=0; virtual int read_first_row(byte *buf, uint primary_key); virtual int restart_rnd_next(byte *buf, byte *pos); - virtual ha_rows records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag) + virtual ha_rows records_in_range(uint inx, key_range *min_key, + key_range *max_key) { return (ha_rows) 10; } virtual void position(const byte *record)=0; virtual my_off_t row_position() { return HA_OFFSET_ERROR; } diff --git a/sql/key.cc b/sql/key.cc index a2c3b2c8989..9425a368669 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -156,9 +156,28 @@ void key_restore(TABLE *table,byte *key,uint idx,uint key_length) } /* key_restore */ - /* Compare if a key has changed */ +/* + Compare if a key has changed -int key_cmp(TABLE *table,const byte *key,uint idx,uint key_length) + SYNOPSIS + key_cmp_if_same() + table TABLE + key key to compare to row + idx Index used + key_length Length of key + + NOTES + In theory we could just call field->cmp() for all field types, + but as we are only interested if a key has changed (not if the key is + larger or smaller than the previous value) we can do things a bit + faster by using memcmp() instead. + + RETURN + 0 If key is equal + 1 Key has changed +*/ + +bool key_cmp_if_same(TABLE *table,const byte *key,uint idx,uint key_length) { uint length; KEY_PART_INFO *key_part; @@ -281,3 +300,56 @@ bool check_if_key_used(TABLE *table, uint idx, List &fields) return check_if_key_used(table, table->primary_key, fields); return 0; } + + +/* + Compare key in row to a given key + + SYNOPSIS + key_cmp() + key_part Key part handler + key Key to compare to value in table->record[0] + key_length length of 'key' + + RETURN + The return value is SIGN(key_in_row - range_key): + + 0 Key is equal to range or 'range' == 0 (no range) + -1 Key is less than range + 1 Key is larger than range +*/ + +int key_cmp(KEY_PART_INFO *key_part, const byte *key, uint key_length) +{ + uint store_length; + + for (const byte *end=key + key_length; + key < end; + key+= store_length, key_part++) + { + int cmp; + store_length= key_part->store_length; + if (key_part->null_bit) + { + /* This key part allows null values; NULL is lower than everything */ + register bool field_is_null= key_part->field->is_null(); + if (*key) // If range key is null + { + /* the range is expecting a null value */ + if (!field_is_null) + return 1; // Found key is > range + /* null -- exact match, go to next key part */ + continue; + } + else if (field_is_null) + return -1; // NULL is less than any value + key++; // Skip null byte + store_length--; + } + if ((cmp=key_part->field->key_cmp((byte*) key, key_part->length)) < 0) + return -1; + if (cmp > 0) + return 1; + } + return 0; // Keys are equal +} diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 8cae95e5070..14bd16332ef 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -754,11 +754,12 @@ void mysql_print_status(THD *thd); int find_ref_key(TABLE *form,Field *field, uint *offset); void key_copy(byte *key,TABLE *form,uint index,uint key_length); void key_restore(TABLE *form,byte *key,uint index,uint key_length); -int key_cmp(TABLE *form,const byte *key,uint index,uint key_length); +bool key_cmp_if_same(TABLE *form,const byte *key,uint index,uint key_length); void key_unpack(String *to,TABLE *form,uint index); bool check_if_key_used(TABLE *table, uint idx, List &fields); -bool init_errmessage(void); +int key_cmp(KEY_PART_INFO *key_part, const byte *key, uint key_length); +bool init_errmessage(void); void sql_perror(const char *message); void sql_print_error(const char *format,...) __attribute__ ((format (printf, 1, 2))); diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 1e7bf90738c..3cc64c35223 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1800,8 +1800,8 @@ SEL_ARG * SEL_ARG::insert(SEL_ARG *key) { SEL_ARG *element,**par,*last_element; - LINT_INIT(par); LINT_INIT(last_element); + for (element= this; element != &null_element ; ) { last_element=element; @@ -2296,26 +2296,32 @@ check_quick_keys(PARAM *param,uint idx,SEL_ARG *key_tree, { if (tmp_min_flag & GEOM_FLAG) { - tmp= param->table->file-> - records_in_range((int) keynr, (byte*)(param->min_key), - min_key_length, - (ha_rkey_function)(tmp_min_flag ^ GEOM_FLAG), - (byte *)NullS, 0, HA_READ_KEY_EXACT); + key_range min_range; + min_range.key= (byte*) param->min_key; + min_range.length= min_key_length; + /* In this case tmp_min_flag contains the handler-read-function */ + min_range.flag= (ha_rkey_function) (tmp_min_flag ^ GEOM_FLAG); + + tmp= param->table->file->records_in_range(keynr, &min_range, + (key_range*) 0); } else { - tmp=param->table->file-> - records_in_range((int) keynr, - (byte*) (!min_key_length ? NullS : - param->min_key), - min_key_length, - tmp_min_flag & NEAR_MIN ? - HA_READ_AFTER_KEY : HA_READ_KEY_EXACT, - (byte*) (!max_key_length ? NullS : - param->max_key), - max_key_length, - (tmp_max_flag & NEAR_MAX ? - HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY)); + key_range min_range, max_range; + + min_range.key= (byte*) param->min_key; + min_range.length= min_key_length; + min_range.flag= (tmp_min_flag & NEAR_MIN ? HA_READ_AFTER_KEY : + HA_READ_KEY_EXACT); + max_range.key= param->max_key; + max_range.length= max_key_length; + max_range.flag= (tmp_max_flag & NEAR_MAX ? + HA_READ_BEFORE_KEY : HA_READ_AFTER_KEY); + tmp=param->table->file->records_in_range(keynr, + (min_key_length ? &min_range : + (key_range*) 0), + (max_key_length ? &max_range : + (key_range*) 0)); } } end: @@ -2604,7 +2610,7 @@ int QUICK_SELECT::get_next() if (range) { // Already read through key - result= file->read_range_next(test(range->flag & EQ_RANGE)); + result= file->read_range_next(); if (result != HA_ERR_END_OF_FILE) DBUG_RETURN(result); } @@ -2628,6 +2634,7 @@ int QUICK_SELECT::get_next() result= file->read_range_first(range->min_length ? &start_key : 0, range->max_length ? &end_key : 0, + test(range->flag & EQ_RANGE), sorted); if (range->flag == (UNIQUE_RANGE | EQ_RANGE)) range=0; // Stop searching @@ -2815,40 +2822,14 @@ int QUICK_SELECT_DESC::get_next() int QUICK_SELECT_DESC::cmp_prev(QUICK_RANGE *range_arg) { + int cmp; if (range_arg->flag & NO_MIN_RANGE) return 0; /* key can't be to small */ - KEY_PART *key_part = key_parts; - uint store_length; - - for (char *key = range_arg->min_key, *end = key + range_arg->min_length; - key < end; - key += store_length, key_part++) - { - int cmp; - store_length= key_part->store_length; - if (key_part->null_bit) - { - // this key part allows null values; NULL is lower than everything else - if (*key) - { - // the range is expecting a null value - if (!key_part->field->is_null()) - return 0; // not null -- still inside the range - continue; // null -- exact match, go to next key part - } - else if (key_part->field->is_null()) - return 1; // null -- outside the range - key++; - store_length--; - } - if ((cmp = key_part->field->key_cmp((byte*) key, - key_part->length)) > 0) - return 0; - if (cmp < 0) - return 1; - } - return (range_arg->flag & NEAR_MIN) ? 1 : 0; // Exact match + cmp= key_cmp(key_part_info, range_arg->min_key, range_arg->min_length); + if (cmp > 0 || cmp == 0 && !(range_arg->flag & NEAR_MIN)) + return 0; + return 1; // outside of range } diff --git a/sql/opt_range.h b/sql/opt_range.h index 2df9d93e1ef..2072ded15d1 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -80,13 +80,18 @@ public: MEM_ROOT alloc; KEY_PART *key_parts; + KEY_PART_INFO *key_part_info; ha_rows records; double read_time; QUICK_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0); virtual ~QUICK_SELECT(); void reset(void) { next=0; it.rewind(); } - int init() { return error=file->index_init(index); } + int init() + { + key_part_info= head->key_info[index].key_part; + return error=file->index_init(index); + } virtual int get_next(); virtual bool reverse_sorted() { return 0; } bool unique_key_range(); diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index 4fdcd093132..8c1cd9ce1cb 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -716,7 +716,7 @@ static bool find_key_for_maxmin(bool max_fl, TABLE_REF *ref, static int reckey_in_range(bool max_fl, TABLE_REF *ref, Field* field, COND *cond, uint range_fl, uint prefix_len) { - if (key_cmp(field->table, ref->key_buff, ref->key, prefix_len)) + if (key_cmp_if_same(field->table, ref->key_buff, ref->key, prefix_len)) return 1; if (!cond || (range_fl & (max_fl ? NO_MIN_RANGE : NO_MAX_RANGE))) return 0; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 9c7fe3e2993..447a5d9ae80 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1820,7 +1820,7 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) } my_hash_insert(&hash_columns, (byte *) mem_check); } while (!col_privs->file->index_next(col_privs->record[0]) && - !key_cmp(col_privs,key,0,key_len)); + !key_cmp_if_same(col_privs,key,0,key_len)); } } @@ -2043,7 +2043,7 @@ static int replace_column_table(GRANT_TABLE *g_t, } } } while (!table->file->index_next(table->record[0]) && - !key_cmp(table,key,0,key_length)); + !key_cmp_if_same(table,key,0,key_length)); } end: diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5db4a0042ea..5e2525f046a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6162,8 +6162,8 @@ join_read_prev_same(READ_RECORD *info) if ((error=table->file->index_prev(table->record[0]))) return report_error(table, error); - if (key_cmp(table, tab->ref.key_buff, tab->ref.key, - tab->ref.key_length)) + if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key, + tab->ref.key_length)) { table->status=STATUS_NOT_FOUND; error= -1; From 3f5ce7bd25397efb7a56a2b1ee0d2c638c3cf3ef Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Mon, 17 May 2004 11:22:30 +0300 Subject: [PATCH 35/47] After merge fixes --- mysql-test/r/type_float.result | 2 +- sql/log_event.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 3dee0c2fcf9..f044ced2342 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -83,7 +83,7 @@ show create table t2; Table Create Table t2 CREATE TABLE `t2` ( `col` double default NULL -) TYPE=MyISAM +) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1,t2; create table t1 (a float); insert into t1 values (1); diff --git a/sql/log_event.cc b/sql/log_event.cc index 9cbcead743f..abbccb32034 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1675,7 +1675,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, thd->db= (char*) rewrite_db(db); DBUG_ASSERT(thd->query == 0); thd->query= 0; // Should not be needed - thd->querty_length= 0; // Should not be needed + thd->query_length= 0; // Should not be needed thd->query_error= 0; clear_all_errors(thd, rli); if (!use_rli_only_for_errors) From bc71d98a039d80cf0281f8745933f3e75a4f376a Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 17 May 2004 11:04:12 +0200 Subject: [PATCH 36/47] bug#3681 - order by, distinct, refer to aliased field by name check for field_name (not only for name) in find_item_in_list, to be compatible with item->eq() that is done later --- mysql-test/r/order_by.result | 4 ++-- sql/sql_base.cc | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 5edffdacc98..694dc26bcde 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -89,10 +89,10 @@ create table t1 ( pk int primary key, name varchar(255) not null, number v insert into t1 values (1, 'Gamma', '123'), (2, 'Gamma Ext', '123a'), (3, 'Alpha', '001'), (4, 'Beta', '200c'); select distinct t1.name as 'Building Name',t1.number as 'Building Number' from t1 order by t1.name asc; Building Name Building Number -Gamma 123 -Gamma Ext 123a Alpha 001 Beta 200c +Gamma 123 +Gamma Ext 123a drop table t1; create table t1 (id int not null,col1 int not null,col2 int not null,index(col1)); insert into t1 values(1,2,2),(2,2,1),(3,1,2),(4,1,1),(5,1,4),(6,2,3),(7,3,1),(8,2,4); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 14a54a410a2..e3fbfb2d0e3 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2103,7 +2103,9 @@ find_item_in_list(Item *find, List &items, uint *counter, => we have to check presence of name before compare */ if (item_field->name && - !my_strcasecmp(system_charset_info, item_field->name, field_name)) + (!my_strcasecmp(system_charset_info, item_field->name, field_name) || + !my_strcasecmp(system_charset_info, + item_field->field_name, field_name))) { if (!table_name) { From eb936575073ba2d75c744f133fcd4a6e95e97993 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 17 May 2004 11:10:22 +0200 Subject: [PATCH 37/47] typo fixed --- sql/ha_heap.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 9915dc90dc1..c375614ac95 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -375,7 +375,7 @@ ha_rows ha_heap::records_in_range(uint inx, key_range *min_key, min_key->length != key->key_length || min_key->flag != HA_READ_KEY_EXACT || max_key->flag != HA_READ_AFTER_KEY) - return HA_POS_ERROR; // Can't only use exact keys + return HA_POS_ERROR; // Can only use exact keys return 10; // Good guess } From 03f19377a91b81b060288cd148407c95ccf542e8 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Mon, 17 May 2004 14:40:31 +0300 Subject: [PATCH 38/47] InnoDB cleanup: Add const qualifiers to many char* arguments --- innobase/dict/dict0dict.c | 64 +++++++------ innobase/dict/dict0load.c | 28 +++--- innobase/dict/dict0mem.c | 42 +++++---- innobase/fil/fil0fil.c | 127 +++++++++++++------------- innobase/include/data0data.h | 2 +- innobase/include/data0data.ic | 2 +- innobase/include/dict0dict.h | 53 ++++++----- innobase/include/dict0dict.ic | 10 +-- innobase/include/dict0load.h | 23 ++--- innobase/include/dict0mem.h | 70 ++++++++------- innobase/include/fil0fil.h | 104 ++++++++++++---------- innobase/include/os0file.h | 156 +++++++++++++++++--------------- innobase/include/os0sync.h | 18 ++-- innobase/include/pars0pars.h | 4 +- innobase/include/pars0sym.h | 4 +- innobase/include/row0mysql.h | 51 +++++------ innobase/include/row0sel.h | 10 +-- innobase/include/trx0roll.h | 4 +- innobase/include/trx0sys.h | 2 +- innobase/include/trx0trx.h | 6 +- innobase/include/ut0rnd.h | 10 +-- innobase/include/ut0rnd.ic | 10 +-- innobase/include/ut0ut.h | 15 ---- innobase/os/os0file.c | 163 ++++++++++++++++++---------------- innobase/os/os0sync.c | 18 ++-- innobase/pars/pars0pars.c | 4 +- innobase/pars/pars0sym.c | 5 +- innobase/row/row0mysql.c | 51 +++++------ innobase/row/row0sel.c | 10 +-- innobase/trx/trx0roll.c | 4 +- innobase/trx/trx0sys.c | 2 +- 31 files changed, 553 insertions(+), 519 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index c9e3ac5ec66..6a6ac2492f8 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -70,7 +70,7 @@ dict_col_reposition_in_cache( /*=========================*/ dict_table_t* table, /* in: table */ dict_col_t* col, /* in: column */ - char* new_name); /* in: new table name */ + const char* new_name); /* in: new table name */ /************************************************************************** Removes a column from the data dictionary hash table. */ static @@ -309,7 +309,7 @@ dict_table_get_index_noninline( /*===========================*/ /* out: index, NULL if does not exist */ dict_table_t* table, /* in: table */ - char* name) /* in: index name */ + const char* name) /* in: index name */ { return(dict_table_get_index(table, name)); } @@ -693,9 +693,10 @@ directory dict_table_get_low is usually the appropriate function. */ dict_table_t* dict_table_get( /*===========*/ - /* out: table, NULL if does not exist */ - char* table_name, /* in: table name */ - trx_t* trx) /* in: transaction handle or NULL */ + /* out: table, NULL if + does not exist */ + const char* table_name, /* in: table name */ + trx_t* trx) /* in: transaction handle or NULL */ { dict_table_t* table; @@ -722,9 +723,10 @@ Returns a table object and increments MySQL open handle count on the table. */ dict_table_t* dict_table_get_and_increment_handle_count( /*======================================*/ - /* out: table, NULL if does not exist */ - char* table_name, /* in: table name */ - trx_t* trx) /* in: transaction handle or NULL */ + /* out: table, NULL if + does not exist */ + const char* table_name, /* in: table name */ + trx_t* trx) /* in: transaction handle or NULL */ { dict_table_t* table; @@ -886,7 +888,7 @@ dict_table_rename_in_cache( /*=======================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table */ - char* new_name, /* in: new name */ + const char* new_name, /* in: new name */ ibool rename_also_foreigns)/* in: in ALTER TABLE we want to preserve the original table name in constraints which reference it */ @@ -1294,7 +1296,7 @@ dict_col_reposition_in_cache( /*=========================*/ dict_table_t* table, /* in: table */ dict_col_t* col, /* in: column */ - char* new_name) /* in: new table name */ + const char* new_name) /* in: new table name */ { ulint fold; @@ -2019,7 +2021,7 @@ dict_foreign_find_index( column types must match */ { dict_index_t* index; - char* col_name; + const char* col_name; ulint i; index = dict_table_get_first_index(table); @@ -2564,14 +2566,14 @@ static char* dict_strip_comments( /*================*/ - /* out, own: SQL string stripped from - comments; the caller must free this - with mem_free()! */ - char* sql_string) /* in: SQL string */ + /* out, own: SQL string stripped from + comments; the caller must free this + with mem_free()! */ + const char* sql_string) /* in: SQL string */ { - char* str; - char* sptr; - char* ptr; + char* str; + const char* sptr; + char* ptr; str = mem_alloc(strlen(sql_string) + 1); @@ -2970,7 +2972,8 @@ col_loop1: } foreign->foreign_table = table; - foreign->foreign_table_name = table->name; + foreign->foreign_table_name = mem_heap_strdup(foreign->heap, + table->name); foreign->foreign_index = index; foreign->n_fields = i; foreign->foreign_col_names = mem_heap_alloc(foreign->heap, @@ -3244,16 +3247,19 @@ allowed to contain more fields than mentioned in the constraint. */ ulint dict_create_foreign_constraints( /*============================*/ - /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create or ALTER TABLE - statement where foreign keys are declared like: - FOREIGN KEY (a, b) REFERENCES table2(c, d), - table2 can be written also with the database - name before it: test.table2; the default - database is the database of parameter name */ - char* name) /* in: table full name in the normalized form - database_name/table_name */ + /* out: error code or DB_SUCCESS */ + trx_t* trx, /* in: transaction */ + const char* sql_string, /* in: table create statement where + foreign keys are declared like: + FOREIGN KEY (a, b) REFERENCES + table2(c, d), table2 can be written + also with the database + name before it: test.table2; the + default database id the database of + parameter name */ + const char* name) /* in: table full name in the + normalized form + database_name/table_name */ { char* str; ulint err; diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index bf8b4582f63..071a3b4c684 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -27,9 +27,10 @@ Finds the first table name in the given database. */ char* dict_get_first_table_name_in_db( /*============================*/ - /* out, own: table name, NULL if does not exist; - the caller must free the memory in the string! */ - char* name) /* in: database name which ends to '/' */ + /* out, own: table name, NULL if + does not exist; the caller must + free the memory in the string! */ + const char* name) /* in: database name which ends to '/' */ { dict_table_t* sys_tables; btr_pcur_t pcur; @@ -389,8 +390,8 @@ Report that an index field or index for a table has been delete marked. */ static void dict_load_report_deleted_index( - char* name, /* in: table name */ - ulint field) /* in: index field, or ULINT_UNDEFINED */ + const char* name, /* in: table name */ + ulint field) /* in: index field, or ULINT_UNDEFINED */ { fputs("InnoDB: Error: data dictionary entry" " for table ", stderr); @@ -688,12 +689,13 @@ dictionary cache. */ dict_table_t* dict_load_table( /*============*/ - /* out: table, NULL if does not exist; if the table is - stored in an .ibd file, but the file does not exist, - then we set the ibd_file_missing flag TRUE in the table - object we return */ - char* name) /* in: table name in the databasename/tablename - format */ + /* out: table, NULL if does not exist; + if the table is stored in an .ibd file, + but the file does not exist, + then we set the ibd_file_missing flag TRUE + in the table object we return */ + const char* name) /* in: table name in the + databasename/tablename format */ { ibool ibd_file_missing = FALSE; dict_table_t* table; @@ -1185,8 +1187,8 @@ already in the dictionary cache. */ ulint dict_load_foreigns( /*===============*/ - /* out: DB_SUCCESS or error code */ - char* table_name) /* in: table name */ + /* out: DB_SUCCESS or error code */ + const char* table_name) /* in: table name */ { btr_pcur_t pcur; mem_heap_t* heap; diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c index a4f83ddd657..936b06b1905 100644 --- a/innobase/dict/dict0mem.c +++ b/innobase/dict/dict0mem.c @@ -30,15 +30,14 @@ dict_table_t* dict_mem_table_create( /*==================*/ /* out, own: table object */ - char* name, /* in: table name */ - ulint space, /* in: space where the clustered index of + const char* name, /* in: table name */ + ulint space, /* in: space where the clustered index of the table is placed; this parameter is ignored if the table is made a member of a cluster */ - ulint n_cols) /* in: number of columns */ + ulint n_cols) /* in: number of columns */ { dict_table_t* table; - char* str; mem_heap_t* heap; ut_ad(name); @@ -48,11 +47,9 @@ dict_mem_table_create( table = mem_heap_alloc(heap, sizeof(dict_table_t)); table->heap = heap; - - str = mem_heap_strdup(heap, name); table->type = DICT_TABLE_ORDINARY; - table->name = str; + table->name = mem_heap_strdup(heap, name); table->space = space; table->ibd_file_missing = FALSE; table->tablespace_discarded = FALSE; @@ -103,11 +100,11 @@ dict_table_t* dict_mem_cluster_create( /*====================*/ /* out, own: cluster object */ - char* name, /* in: cluster name */ - ulint space, /* in: space where the clustered indexes + const char* name, /* in: cluster name */ + ulint space, /* in: space where the clustered indexes of the member tables are placed */ - ulint n_cols, /* in: number of columns */ - ulint mix_len) /* in: length of the common key prefix in the + ulint n_cols, /* in: number of columns */ + ulint mix_len)/* in: length of the common key prefix in the cluster */ { dict_table_t* cluster; @@ -127,7 +124,7 @@ void dict_mem_table_make_cluster_member( /*===============================*/ dict_table_t* table, /* in: non-published table */ - char* cluster_name) /* in: cluster name */ + const char* cluster_name) /* in: cluster name */ { table->type = DICT_TABLE_CLUSTER_MEMBER; table->cluster_name = cluster_name; @@ -140,7 +137,7 @@ void dict_mem_table_add_col( /*===================*/ dict_table_t* table, /* in: table */ - char* name, /* in: column name */ + const char* name, /* in: column name */ ulint mtype, /* in: main datatype */ ulint prtype, /* in: precise type */ ulint len, /* in: length */ @@ -174,14 +171,15 @@ Creates an index memory object. */ dict_index_t* dict_mem_index_create( /*==================*/ - /* out, own: index object */ - char* table_name, /* in: table name */ - char* index_name, /* in: index name */ - ulint space, /* in: space where the index tree is placed, - ignored if the index is of the clustered - type */ - ulint type, /* in: DICT_UNIQUE, DICT_CLUSTERED, ... ORed */ - ulint n_fields) /* in: number of fields */ + /* out, own: index object */ + const char* table_name, /* in: table name */ + const char* index_name, /* in: index name */ + ulint space, /* in: space where the index tree is + placed, ignored if the index is of + the clustered type */ + ulint type, /* in: DICT_UNIQUE, + DICT_CLUSTERED, ... ORed */ + ulint n_fields) /* in: number of fields */ { dict_index_t* index; mem_heap_t* heap; @@ -259,7 +257,7 @@ void dict_mem_index_add_field( /*=====================*/ dict_index_t* index, /* in: index */ - char* name, /* in: column name */ + const char* name, /* in: column name */ ulint order, /* in: order criterion; 0 means an ascending order */ ulint prefix_len) /* in: 0 or the column prefix length diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index b9aff246802..28eea0ba188 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -390,11 +390,12 @@ Appends a new file to the chain of files of a space. File must be closed. */ void fil_node_create( /*============*/ - char* name, /* in: file name (file must be closed) */ - ulint size, /* in: file size in database blocks, rounded downwards - to an integer */ - ulint id, /* in: space id where to append */ - ibool is_raw) /* in: TRUE if a raw device or a raw disk partition */ + const char* name, /* in: file name (file must be closed) */ + ulint size, /* in: file size in database blocks, rounded + downwards to an integer */ + ulint id, /* in: space id where to append */ + ibool is_raw) /* in: TRUE if a raw device or + a raw disk partition */ { fil_system_t* system = fil_system; fil_node_t* node; @@ -804,10 +805,10 @@ there is an error, prints an error message to the .err log. */ ibool fil_space_create( /*=============*/ - /* out: TRUE if success */ - char* name, /* in: space name */ - ulint id, /* in: space id */ - ulint purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */ + /* out: TRUE if success */ + const char* name, /* in: space name */ + ulint id, /* in: space id */ + ulint purpose)/* in: FIL_TABLESPACE, or FIL_LOG if log */ { fil_system_t* system = fil_system; fil_space_t* space; @@ -1542,16 +1543,18 @@ static void fil_op_write_log( /*=============*/ - ulint type, /* in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or - MLOG_FILE_RENAME */ - ulint space_id, /* in: space id */ - char* name, /* in: table name in the familiar - 'databasename/tablename' format, or the file - path in the case of MLOG_FILE_DELETE */ - char* new_name, /* in: if type is MLOG_FILE_RENAME, the new - table name in the 'databasename/tablename' - format */ - mtr_t* mtr) /* in: mini-transaction handle */ + ulint type, /* in: MLOG_FILE_CREATE, + MLOG_FILE_DELETE, or + MLOG_FILE_RENAME */ + ulint space_id, /* in: space id */ + const char* name, /* in: table name in the familiar + 'databasename/tablename' format, or + the file path in the case of + MLOG_FILE_DELETE */ + const char* new_name, /* in: if type is MLOG_FILE_RENAME, + the new table name in the + 'databasename/tablename' format */ + mtr_t* mtr) /* in: mini-transaction handle */ { byte* log_ptr; @@ -1960,14 +1963,15 @@ tablespace memory cache. */ ibool fil_rename_tablespace( /*==================*/ - /* out: TRUE if success */ - char* old_name, /* in: old table name in the standard - databasename/tablename format of InnoDB, or - NULL if we do the rename based on the space - id only */ - ulint id, /* in: space id */ - char* new_name) /* in: new table name in the standard - databasename/tablename format of InnoDB */ + /* out: TRUE if success */ + const char* old_name, /* in: old table name in the standard + databasename/tablename format of + InnoDB, or NULL if we do the rename + based on the space id only */ + ulint id, /* in: space id */ + const char* new_name) /* in: new table name in the standard + databasename/tablename format + of InnoDB */ { fil_system_t* system = fil_system; ibool success; @@ -2124,15 +2128,16 @@ path '.'. */ ulint fil_create_new_single_table_tablespace( /*===================================*/ - /* out: DB_SUCCESS or error code */ - ulint* space_id, /* in/out: space id; if this is != 0, then - this is an input parameter, otherwise - output */ - char* tablename, /* in: the table name in the usual - databasename/tablename format of InnoDB */ - ulint size) /* in: the initial size of the tablespace file - in pages, must be >= FIL_IBD_FILE_INITIAL_SIZE - */ + /* out: DB_SUCCESS or error code */ + ulint* space_id, /* in/out: space id; if this is != 0, + then this is an input parameter, + otherwise output */ + const char* tablename, /* in: the table name in the usual + databasename/tablename format + of InnoDB */ + ulint size) /* in: the initial size of the + tablespace file in pages, + must be >= FIL_IBD_FILE_INITIAL_SIZE */ { os_file_t file; ibool ret; @@ -2293,12 +2298,12 @@ lsn's just by looking at that flush lsn. */ ibool fil_reset_too_high_lsns( /*====================*/ - /* out: TRUE if success */ - char* name, /* in: table name in the databasename/tablename - format */ - dulint current_lsn) /* in: reset lsn's if the lsn stamped to - FIL_PAGE_FILE_FLUSH_LSN in the first page is - too high */ + /* out: TRUE if success */ + const char* name, /* in: table name in the + databasename/tablename format */ + dulint current_lsn) /* in: reset lsn's if the lsn stamped + to FIL_PAGE_FILE_FLUSH_LSN in the + first page is too high */ { os_file_t file; char* filepath; @@ -2433,10 +2438,10 @@ closes it after we have looked at the space id in it. */ ibool fil_open_single_table_tablespace( /*=============================*/ - /* out: TRUE if success */ - ulint id, /* in: space id */ - char* name) /* in: table name in the databasename/tablename - format */ + /* out: TRUE if success */ + ulint id, /* in: space id */ + const char* name) /* in: table name in the + databasename/tablename format */ { os_file_t file; char* filepath; @@ -2937,20 +2942,22 @@ there may be many tablespaces which are not yet in the memory cache. */ ibool fil_space_for_table_exists_in_mem( /*==============================*/ - /* out: TRUE if a matching tablespace exists - in the memory cache */ - ulint id, /* in: space id */ - char* name, /* in: table name in the standard - 'databasename/tablename' format */ - ibool mark_space, /* in: in crash recovery, at database startup - we mark all spaces which have an associated - table in the InnoDB data dictionary, so that - we can print a warning about orphaned - tablespaces */ - ibool print_error_if_does_not_exist) - /* in: print detailed error information to - the .err log if a matching tablespace is - not found from memory */ + /* out: TRUE if a matching tablespace + exists in the memory cache */ + ulint id, /* in: space id */ + const char* name, /* in: table name in the standard + 'databasename/tablename' format */ + ibool mark_space, /* in: in crash recovery, at database + startup we mark all spaces which have + an associated table in the InnoDB + data dictionary, so that + we can print a warning about orphaned + tablespaces */ + ibool print_error_if_does_not_exist) + /* in: print detailed error + information to the .err log if a + matching tablespace is not found from + memory */ { fil_system_t* system = fil_system; fil_space_t* namespace; diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index 99d3c297039..e2de13d0520 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -86,7 +86,7 @@ void dfield_set_data( /*============*/ dfield_t* field, /* in: field */ - void* data, /* in: data */ + const void* data, /* in: data */ ulint len); /* in: length or UNIV_SQL_NULL */ /************************************************************************** Writes an SQL null field full of zeros. */ diff --git a/innobase/include/data0data.ic b/innobase/include/data0data.ic index 697a272ccd6..569bf898801 100644 --- a/innobase/include/data0data.ic +++ b/innobase/include/data0data.ic @@ -93,7 +93,7 @@ void dfield_set_data( /*============*/ dfield_t* field, /* in: field */ - void* data, /* in: data */ + const void* data, /* in: data */ ulint len) /* in: length or UNIV_SQL_NULL */ { ut_ad(field); diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 98636f6e1cb..fe04359d6f1 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -166,7 +166,7 @@ dict_table_rename_in_cache( /*=======================*/ /* out: TRUE if success */ dict_table_t* table, /* in: table */ - char* new_name, /* in: new name */ + const char* new_name, /* in: new name */ ibool rename_also_foreigns);/* in: in ALTER TABLE we want to preserve the original table name in constraints which reference it */ @@ -210,16 +210,19 @@ fields than mentioned in the constraint. */ ulint dict_create_foreign_constraints( /*============================*/ - /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create statement where - foreign keys are declared like: - FOREIGN KEY (a, b) REFERENCES table2(c, d), - table2 can be written also with the database - name before it: test.table2; the default - database id the database of parameter name */ - char* name); /* in: table full name in the normalized form - database_name/table_name */ + /* out: error code or DB_SUCCESS */ + trx_t* trx, /* in: transaction */ + const char* sql_string, /* in: table create statement where + foreign keys are declared like: + FOREIGN KEY (a, b) REFERENCES + table2(c, d), table2 can be written + also with the database + name before it: test.table2; the + default database id the database of + parameter name */ + const char* name); /* in: table full name in the + normalized form + database_name/table_name */ /************************************************************************** Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. */ @@ -246,9 +249,10 @@ directory dict_table_get_low is usually the appropriate function. */ dict_table_t* dict_table_get( /*===========*/ - /* out: table, NULL if does not exist */ - char* table_name, /* in: table name */ - trx_t* trx); /* in: transaction handle */ + /* out: table, NULL if + does not exist */ + const char* table_name, /* in: table name */ + trx_t* trx); /* in: transaction handle */ /************************************************************************** Returns a table object and increments MySQL open handle count on the table. */ @@ -256,9 +260,10 @@ Returns a table object and increments MySQL open handle count on the table. dict_table_t* dict_table_get_and_increment_handle_count( /*======================================*/ - /* out: table, NULL if does not exist */ - char* table_name, /* in: table name */ - trx_t* trx); /* in: transaction handle or NULL */ + /* out: table, NULL if + does not exist */ + const char* table_name, /* in: table name */ + trx_t* trx); /* in: transaction handle or NULL */ /************************************************************************** Returns a table object, based on table id, and memoryfixes it. */ @@ -290,8 +295,8 @@ UNIV_INLINE dict_table_t* dict_table_check_if_in_cache_low( /*==============================*/ - /* out: table, NULL if not found */ - char* table_name); /* in: table name */ + /* out: table, NULL if not found */ + const char* table_name); /* in: table name */ /************************************************************************** Gets a table; loads it to the dictionary cache if necessary. A low-level function. */ @@ -299,8 +304,8 @@ UNIV_INLINE dict_table_t* dict_table_get_low( /*===============*/ - /* out: table, NULL if not found */ - char* table_name); /* in: table name */ + /* out: table, NULL if not found */ + const char* table_name); /* in: table name */ /************************************************************************** Returns an index object. */ UNIV_INLINE @@ -309,7 +314,7 @@ dict_table_get_index( /*=================*/ /* out: index, NULL if does not exist */ dict_table_t* table, /* in: table */ - char* name); /* in: index name */ + const char* name); /* in: index name */ /************************************************************************** Returns an index object. */ @@ -318,7 +323,7 @@ dict_table_get_index_noninline( /*===========================*/ /* out: index, NULL if does not exist */ dict_table_t* table, /* in: table */ - char* name); /* in: index name */ + const char* name); /* in: index name */ /************************************************************************** Prints a table data. */ @@ -340,7 +345,7 @@ Prints a table data when we know the table name. */ void dict_table_print_by_name( /*=====================*/ - char* name); + const char* name); #endif /* UNIV_DEBUG */ /************************************************************************** Outputs info on foreign keys of a table. */ diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index 57ef4b896f5..0f7cc8973db 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -536,8 +536,8 @@ UNIV_INLINE dict_table_t* dict_table_check_if_in_cache_low( /*==============================*/ - /* out: table, NULL if not found */ - char* table_name) /* in: table name */ + /* out: table, NULL if not found */ + const char* table_name) /* in: table name */ { dict_table_t* table; ulint table_fold; @@ -562,8 +562,8 @@ UNIV_INLINE dict_table_t* dict_table_get_low( /*===============*/ - /* out: table, NULL if not found */ - char* table_name) /* in: table name */ + /* out: table, NULL if not found */ + const char* table_name) /* in: table name */ { dict_table_t* table; @@ -642,7 +642,7 @@ dict_table_get_index( /*=================*/ /* out: index, NULL if does not exist */ dict_table_t* table, /* in: table */ - char* name) /* in: index name */ + const char* name) /* in: index name */ { dict_index_t* index = NULL; diff --git a/innobase/include/dict0load.h b/innobase/include/dict0load.h index f7168a0f45f..d4dccb33373 100644 --- a/innobase/include/dict0load.h +++ b/innobase/include/dict0load.h @@ -31,9 +31,10 @@ Finds the first table name in the given database. */ char* dict_get_first_table_name_in_db( /*============================*/ - /* out, own: table name, NULL if does not exist; - the caller must free the memory in the string! */ - char* name); /* in: database name which ends to '/' */ + /* out, own: table name, NULL if + does not exist; the caller must free + the memory in the string! */ + const char* name); /* in: database name which ends to '/' */ /************************************************************************ Loads a table definition and also all its index definitions, and also the cluster definition if the table is a member in a cluster. Also loads @@ -43,11 +44,13 @@ a foreign key references columns in this table. */ dict_table_t* dict_load_table( /*============*/ - /* out: table, NULL if does not exist; if the table is - stored in an .ibd file, but the file does not exist, - then we set the ibd_file_missing flag TRUE in the table - object we return */ - char* name); /* in: table name */ + /* out: table, NULL if does not exist; + if the table is stored in an .ibd file, + but the file does not exist, + then we set the ibd_file_missing flag TRUE + in the table object we return */ + const char* name); /* in: table name in the + databasename/tablename format */ /*************************************************************************** Loads a table object based on the table id. */ @@ -75,8 +78,8 @@ already in the dictionary cache. */ ulint dict_load_foreigns( /*===============*/ - /* out: DB_SUCCESS or error code */ - char* table_name); /* in: table name */ + /* out: DB_SUCCESS or error code */ + const char* table_name); /* in: table name */ /************************************************************************ Prints to the standard output information on all tables found in the data dictionary system table. */ diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 674868c9fce..f141ea9da09 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -48,27 +48,28 @@ Creates a table memory object. */ dict_table_t* dict_mem_table_create( /*==================*/ - /* out, own: table object */ - char* name, /* in: table name */ - ulint space, /* in: space where the clustered index of - the table is placed; this parameter is - ignored if the table is made a member of - a cluster */ - ulint n_cols); /* in: number of columns */ + /* out, own: table object */ + const char* name, /* in: table name */ + ulint space, /* in: space where the clustered index + of the table is placed; this parameter + is ignored if the table is made + a member of a cluster */ + ulint n_cols); /* in: number of columns */ /************************************************************************** Creates a cluster memory object. */ dict_cluster_t* dict_mem_cluster_create( /*====================*/ - /* out, own: cluster object (where the type - dict_cluster_t == dict_table_t) */ - char* name, /* in: cluster name */ - ulint space, /* in: space where the clustered indexes - of the member tables are placed */ - ulint n_cols, /* in: number of columns */ - ulint mix_len); /* in: length of the common key prefix in the - cluster */ + /* out, own: cluster object (where the + type dict_cluster_t == dict_table_t) */ + const char* name, /* in: cluster name */ + ulint space, /* in: space where the clustered + indexes of the member tables are + placed */ + ulint n_cols, /* in: number of columns */ + ulint mix_len); /* in: length of the common key prefix + in the cluster */ /************************************************************************** Declares a non-published table as a member in a cluster. */ @@ -76,7 +77,7 @@ void dict_mem_table_make_cluster_member( /*===============================*/ dict_table_t* table, /* in: non-published table */ - char* cluster_name); /* in: cluster name */ + const char* cluster_name); /* in: cluster name */ /************************************************************************** Adds a column definition to a table. */ @@ -84,7 +85,7 @@ void dict_mem_table_add_col( /*===================*/ dict_table_t* table, /* in: table */ - char* name, /* in: column name */ + const char* name, /* in: column name */ ulint mtype, /* in: main datatype */ ulint prtype, /* in: precise type */ ulint len, /* in: length */ @@ -95,14 +96,15 @@ Creates an index memory object. */ dict_index_t* dict_mem_index_create( /*==================*/ - /* out, own: index object */ - char* table_name, /* in: table name */ - char* index_name, /* in: index name */ - ulint space, /* in: space where the index tree is placed, - ignored if the index is of the clustered - type */ - ulint type, /* in: DICT_UNIQUE, DICT_CLUSTERED, ... ORed */ - ulint n_fields); /* in: number of fields */ + /* out, own: index object */ + const char* table_name, /* in: table name */ + const char* index_name, /* in: index name */ + ulint space, /* in: space where the index tree is + placed, ignored if the index is of + the clustered type */ + ulint type, /* in: DICT_UNIQUE, + DICT_CLUSTERED, ... ORed */ + ulint n_fields); /* in: number of fields */ /************************************************************************** Adds a field definition to an index. NOTE: does not take a copy of the column name if the field is a column. The memory occupied @@ -112,7 +114,7 @@ void dict_mem_index_add_field( /*=====================*/ dict_index_t* index, /* in: index */ - char* name, /* in: column name */ + const char* name, /* in: column name */ ulint order, /* in: order criterion; 0 means an ascending order */ ulint prefix_len); /* in: 0 or the column prefix length @@ -142,7 +144,7 @@ struct dict_col_struct{ clustered index */ ulint ord_part;/* count of how many times this column appears in ordering fields of an index */ - char* name; /* name */ + const char* name; /* name */ dtype_t type; /* data type */ dict_table_t* table; /* back pointer to table of this column */ ulint aux; /* this is used as an auxiliary variable @@ -154,7 +156,7 @@ struct dict_col_struct{ /* Data structure for a field in an index */ struct dict_field_struct{ dict_col_t* col; /* pointer to the table column */ - char* name; /* name of the column */ + const char* name; /* name of the column */ ulint order; /* flags for ordering this field: DICT_DESCEND, ... */ ulint prefix_len; /* 0 or the length of the column @@ -197,8 +199,8 @@ struct dict_index_struct{ dulint id; /* id of the index */ mem_heap_t* heap; /* memory heap */ ulint type; /* index type */ - char* name; /* index name */ - char* table_name; /* table name */ + const char* name; /* index name */ + const char* table_name; /* table name */ dict_table_t* table; /* back pointer to table */ ulint space; /* space where the index tree is placed */ ulint page_no;/* page number of the index tree root */ @@ -254,12 +256,12 @@ struct dict_foreign_struct{ or DICT_FOREIGN_ON_DELETE_SET_NULL */ char* foreign_table_name;/* foreign table name */ dict_table_t* foreign_table; /* table where the foreign key is */ - char** foreign_col_names;/* names of the columns in the + const char** foreign_col_names;/* names of the columns in the foreign key */ char* referenced_table_name;/* referenced table name */ dict_table_t* referenced_table;/* table where the referenced key is */ - char** referenced_col_names;/* names of the referenced + const char** referenced_col_names;/* names of the referenced columns in the referenced table */ ulint n_fields; /* number of indexes' first fields for which the the foreign key @@ -295,7 +297,7 @@ struct dict_table_struct{ dulint id; /* id of the table or cluster */ ulint type; /* DICT_TABLE_ORDINARY, ... */ mem_heap_t* heap; /* memory heap */ - char* name; /* table name */ + const char* name; /* table name */ ulint space; /* space where the clustered index of the table is placed */ ibool ibd_file_missing;/* TRUE if this is in a single-table @@ -363,7 +365,7 @@ struct dict_table_struct{ byte mix_id_buf[12]; /* mix id of a mixed table written in a compressed form */ - char* cluster_name; /* if the table is a member in a + const char* cluster_name; /* if the table is a member in a cluster, this is the name of the cluster */ /*----------------------*/ ibool does_not_fit_in_memory; diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h index f7cdeb7f195..b750e9b38f2 100644 --- a/innobase/include/fil0fil.h +++ b/innobase/include/fil0fil.h @@ -132,11 +132,12 @@ Appends a new file to the chain of files of a space. File must be closed. */ void fil_node_create( /*============*/ - char* name, /* in: file name (file must be closed) */ - ulint size, /* in: file size in database blocks, rounded downwards - to an integer */ - ulint id, /* in: space id where to append */ - ibool is_raw);/* in: TRUE if a raw device or a raw disk partition */ + const char* name, /* in: file name (file must be closed) */ + ulint size, /* in: file size in database blocks, rounded + downwards to an integer */ + ulint id, /* in: space id where to append */ + ibool is_raw);/* in: TRUE if a raw device or + a raw disk partition */ /******************************************************************** Drops files from the start of a file space, so that its size is cut by the amount given. */ @@ -155,10 +156,10 @@ there is an error, prints an error message to the .err log. */ ibool fil_space_create( /*=============*/ - /* out: TRUE if success */ - char* name, /* in: space name */ - ulint id, /* in: space id */ - ulint purpose);/* in: FIL_TABLESPACE, or FIL_LOG if log */ + /* out: TRUE if success */ + const char* name, /* in: space name */ + ulint id, /* in: space id */ + ulint purpose);/* in: FIL_TABLESPACE, or FIL_LOG if log */ /*********************************************************************** Frees a space object from a the tablespace memory cache. Closes the files in the chain but does not delete them. */ @@ -327,14 +328,15 @@ tablespace memory cache. */ ibool fil_rename_tablespace( /*==================*/ - /* out: TRUE if success */ - char* old_name, /* in: old table name in the standard - databasename/tablename format of InnoDB, or - NULL if we do the rename based on the space - id only */ - ulint id, /* in: space id */ - char* new_name); /* in: new table name in the standard - databasename/tablename format of InnoDB */ + /* out: TRUE if success */ + const char* old_name, /* in: old table name in the standard + databasename/tablename format of + InnoDB, or NULL if we do the rename + based on the space id only */ + ulint id, /* in: space id */ + const char* new_name); /* in: new table name in the standard + databasename/tablename format + of InnoDB */ /*********************************************************************** Creates a new single-table tablespace to a database directory of MySQL. Database directories are under the 'datadir' of MySQL. The datadir is the @@ -344,14 +346,16 @@ path '.'. */ ulint fil_create_new_single_table_tablespace( /*===================================*/ - /* out: DB_SUCCESS or error code */ - ulint* space_id, /* in/out: space id; if this is != 0, then - this is an input parameter, otherwise - output */ - char* tablename, /* in: the table name in the usual - databasename/tablename format of InnoDB */ - ulint size); /* in: the initial size of the tablespace file - in pages, must be > 0 */ + /* out: DB_SUCCESS or error code */ + ulint* space_id, /* in/out: space id; if this is != 0, + then this is an input parameter, + otherwise output */ + const char* tablename, /* in: the table name in the usual + databasename/tablename format + of InnoDB */ + ulint size); /* in: the initial size of the + tablespace file in pages, + must be >= FIL_IBD_FILE_INITIAL_SIZE */ /************************************************************************ Tries to open a single-table tablespace and checks the space id is right in it. If does not succeed, prints an error message to the .err log. This @@ -362,10 +366,10 @@ protection of the dictionary mutex, so that two users cannot race here. */ ibool fil_open_single_table_tablespace( /*=============================*/ - /* out: TRUE if success */ - ulint id, /* in: space id */ - char* name); /* in: table name in the databasename/tablename - format */ + /* out: TRUE if success */ + ulint id, /* in: space id */ + const char* name); /* in: table name in the + databasename/tablename format */ /************************************************************************ It is possible, though very improbable, that the lsn's in the tablespace to be imported have risen above the current system lsn, if a lengthy purge, ibuf @@ -379,12 +383,12 @@ lsn's just by looking at that flush lsn. */ ibool fil_reset_too_high_lsns( /*====================*/ - /* out: TRUE if success */ - char* name, /* in: table name in the databasename/tablename - format */ - dulint current_lsn); /* in: reset lsn's if the lsn stamped to - FIL_PAGE_FILE_FLUSH_LSN in the first page is - too high */ + /* out: TRUE if success */ + const char* name, /* in: table name in the + databasename/tablename format */ + dulint current_lsn); /* in: reset lsn's if the lsn stamped + to FIL_PAGE_FILE_FLUSH_LSN in the + first page is too high */ /************************************************************************ At the server startup, if we need crash recovery, scans the database directories under the MySQL datadir, looking for .ibd files. Those files are @@ -436,20 +440,22 @@ there may be many tablespaces which are not yet in the memory cache. */ ibool fil_space_for_table_exists_in_mem( /*==============================*/ - /* out: TRUE if a matching tablespace - exists in the memory cache */ - ulint id, /* in: space id */ - char* name, /* in: table name in the standard - 'databasename/tablename' format */ - ibool mark_space, /* in: in crash recovery, at database startup - we mark all spaces which have an associated - table in the InnoDB data dictionary, so that - we can print a warning about orphaned - tablespaces */ - ibool print_error_if_does_not_exist); - /* in: print detailed error information to - the .err log if a matching tablespace is - not found from memory */ + /* out: TRUE if a matching tablespace + exists in the memory cache */ + ulint id, /* in: space id */ + const char* name, /* in: table name in the standard + 'databasename/tablename' format */ + ibool mark_space, /* in: in crash recovery, at database + startup we mark all spaces which have + an associated table in the InnoDB + data dictionary, so that + we can print a warning about orphaned + tablespaces */ + ibool print_error_if_does_not_exist); + /* in: print detailed error + information to the .err log if a + matching tablespace is not found from + memory */ /************************************************************************** Tries to extend a data file so that it would accommodate the number of pages given. The tablespace must be cached in the memory cache. If the space is big diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 3eccfcd3be5..930390241d3 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -177,13 +177,15 @@ and '..' items at the start of the directory listing. */ os_file_dir_t os_file_opendir( /*============*/ - /* out: directory stream, NULL if error */ - char* dirname, /* in: directory name; it must not contain - a trailing '\' or '/' */ - ibool error_is_fatal);/* in: TRUE if we should treat an error as a - fatal error; if we try to open symlinks then - we do not wish a fatal error if it happens - not to be a directory */ + /* out: directory stream, NULL if + error */ + const char* dirname, /* in: directory name; it must not + contain a trailing '\' or '/' */ + ibool error_is_fatal);/* in: TRUE if we should treat an + error as a fatal error; if we try to + open symlinks then we do not wish a + fatal error if it happens not to be + a directory */ /*************************************************************************** Closes a directory stream. */ @@ -201,7 +203,7 @@ os_file_readdir_next_file( /*======================*/ /* out: 0 if ok, -1 if error, 1 if at the end of the directory */ - char* dirname,/* in: directory name or path */ + const char* dirname,/* in: directory name or path */ os_file_dir_t dir, /* in: directory stream */ os_file_stat_t* info); /* in/out: buffer where the info is returned */ /********************************************************************* @@ -213,81 +215,89 @@ fail_if_exists arguments is true. */ ibool os_file_create_directory( /*=====================*/ - /* out: TRUE if call succeeds, FALSE on - error */ - char* pathname, /* in: directory name as null-terminated - string */ - ibool fail_if_exists);/* in: if TRUE, pre-existing directory is - treated as an error. */ + /* out: TRUE if call succeeds, + FALSE on error */ + const char* pathname, /* in: directory name as + null-terminated string */ + ibool fail_if_exists);/* in: if TRUE, pre-existing directory + is treated as an error. */ /******************************************************************** A simple function to open or create a file. */ os_file_t os_file_create_simple( /*==================*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error), or - OS_FILE_CREATE_PATH if new file (if exists, error) and - subdirectories along its path are created (if needed)*/ - ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */ - ibool* success);/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file is + opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error), or + OS_FILE_CREATE_PATH if new file + (if exists, error) and subdirectories along + its path are created (if needed)*/ + ulint access_type,/* in: OS_FILE_READ_ONLY or + OS_FILE_READ_WRITE */ + ibool* success);/* out: TRUE if succeed, FALSE if error */ /******************************************************************** A simple function to open or create a file. */ os_file_t os_file_create_simple_no_error_handling( /*====================================*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error) */ - ulint access_type,/* in: OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or - OS_FILE_READ_ALLOW_DELETE; the last option is used by - a backup program reading the file */ - ibool* success);/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file + is opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error) */ + ulint access_type,/* in: OS_FILE_READ_ONLY, + OS_FILE_READ_WRITE, or + OS_FILE_READ_ALLOW_DELETE; the last option is + used by a backup program reading the file */ + ibool* success);/* out: TRUE if succeed, FALSE if error */ /******************************************************************** Opens an existing file or creates a new. */ os_file_t os_file_create( /*===========*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error), OS_FILE_OVERWRITE - if a new file is created or an old overwritten; - OS_FILE_OPEN_RAW, if a raw device or disk partition - should be opened */ - ulint purpose,/* in: OS_FILE_AIO, if asynchronous, non-buffered i/o - is desired, OS_FILE_NORMAL, if any normal file; - NOTE that it also depends on type, os_aio_.. and srv_.. - variables whether we really use async i/o or - unbuffered i/o: look in the function source code for - the exact rules */ - ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */ - ibool* success);/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file + is opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error), + OS_FILE_OVERWRITE if a new file is created + or an old overwritten; + OS_FILE_OPEN_RAW, if a raw device or disk + partition should be opened */ + ulint purpose,/* in: OS_FILE_AIO, if asynchronous, + non-buffered i/o is desired, + OS_FILE_NORMAL, if any normal file; + NOTE that it also depends on type, os_aio_.. + and srv_.. variables whether we really use + async i/o or unbuffered i/o: look in the + function source code for the exact rules */ + ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */ + ibool* success);/* out: TRUE if succeed, FALSE if error */ /*************************************************************************** Deletes a file. The file has to be closed before calling this. */ ibool os_file_delete( /*===========*/ - /* out: TRUE if success */ - char* name); /* in: file path as a null-terminated string */ + /* out: TRUE if success */ + const char* name); /* in: file path as a null-terminated string */ /*************************************************************************** Deletes a file if it exists. The file has to be closed before calling this. */ @@ -295,8 +305,8 @@ Deletes a file if it exists. The file has to be closed before calling this. */ ibool os_file_delete_if_exists( /*=====================*/ - /* out: TRUE if success */ - char* name); /* in: file path as a null-terminated string */ + /* out: TRUE if success */ + const char* name); /* in: file path as a null-terminated string */ /*************************************************************************** Renames a file (can also move it to another directory). It is safest that the file is closed before calling this function. */ @@ -304,10 +314,10 @@ file is closed before calling this function. */ ibool os_file_rename( /*===========*/ - /* out: TRUE if success */ - char* oldpath, /* in: old file path as a null-terminated - string */ - char* newpath); /* in: new file path */ + /* out: TRUE if success */ + const char* oldpath, /* in: old file path as a + null-terminated string */ + const char* newpath); /* in: new file path */ /*************************************************************************** Closes a file handle. In case of error, error number can be retrieved with os_file_get_last_error. */ @@ -351,7 +361,7 @@ ibool os_file_set_size( /*=============*/ /* out: TRUE if success */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ ulint size, /* in: least significant 32 bits of file @@ -426,10 +436,10 @@ os_file_write( /*==========*/ /* out: TRUE if request was successful, FALSE if fail */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ - void* buf, /* in: buffer from which to write */ + const void* buf, /* in: buffer from which to write */ ulint offset, /* in: least significant 32 bits of file offset where to write */ ulint offset_high,/* in: most significant 32 bits of @@ -442,8 +452,8 @@ ibool os_file_status( /*===========*/ /* out: TRUE if call succeeded */ - char * path, /* in: pathname of the file */ - ibool * exists, /* out: TRUE if file exists */ + const char* path, /* in: pathname of the file */ + ibool* exists, /* out: TRUE if file exists */ os_file_type_t* type); /* out: type of the file (if it exists) */ /******************************************************************** The function os_file_dirname returns a directory component of a @@ -478,7 +488,7 @@ os_file_dirname( /*============*/ /* out, own: directory component of the pathname */ - char* path); /* in: pathname */ + const char* path); /* in: pathname */ /******************************************************************** Creates all missing subdirectories along the given path. */ @@ -487,7 +497,7 @@ os_file_create_subdirs_if_needed( /*=============================*/ /* out: TRUE if call succeeded FALSE otherwise */ - char* path); /* in: path name */ + const char* path); /* in: path name */ /**************************************************************************** Initializes the asynchronous io system. Creates separate aio array for non-ibuf read and write, a third aio array for the ibuf i/o, with just one @@ -527,7 +537,7 @@ os_aio( because i/os are not actually handled until all have been posted: use with great caution! */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ void* buf, /* in: buffer where to read or from which diff --git a/innobase/include/os0sync.h b/innobase/include/os0sync.h index e1cf263216e..d27b1676f1b 100644 --- a/innobase/include/os0sync.h +++ b/innobase/include/os0sync.h @@ -87,9 +87,9 @@ explicitly by calling sync_os_reset_event. */ os_event_t os_event_create( /*============*/ - /* out: the event handle */ - char* name); /* in: the name of the event, if NULL - the event is created without a name */ + /* out: the event handle */ + const char* name); /* in: the name of the event, if NULL + the event is created without a name */ #ifdef __WIN__ /************************************************************* Creates an auto-reset event semaphore, i.e., an event which is automatically @@ -98,9 +98,9 @@ reset when a single thread is released. Works only in Windows. */ os_event_t os_event_create_auto( /*=================*/ - /* out: the event handle */ - char* name); /* in: the name of the event, if NULL - the event is created without a name */ + /* out: the event handle */ + const char* name); /* in: the name of the event, if NULL + the event is created without a name */ #endif /************************************************************** Sets an event semaphore to the signaled state: lets waiting threads @@ -171,9 +171,9 @@ mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */ os_mutex_t os_mutex_create( /*============*/ - /* out: the mutex handle */ - char* name); /* in: the name of the mutex, if NULL - the mutex is created without a name */ + /* out: the mutex handle */ + const char* name); /* in: the name of the mutex, if NULL + the mutex is created without a name */ /************************************************************** Acquires ownership of a mutex semaphore. */ diff --git a/innobase/include/pars0pars.h b/innobase/include/pars0pars.h index c260557c424..28985e2f9d0 100644 --- a/innobase/include/pars0pars.h +++ b/innobase/include/pars0pars.h @@ -74,8 +74,8 @@ Parses an SQL string returning the query graph. */ que_t* pars_sql( /*=====*/ - /* out, own: the query graph */ - char* str); /* in: SQL string */ + /* out, own: the query graph */ + const char* str); /* in: SQL string */ /***************************************************************** Retrieves characters to the lexical analyzer. */ diff --git a/innobase/include/pars0sym.h b/innobase/include/pars0sym.h index 3060fd06c8f..a40523861dd 100644 --- a/innobase/include/pars0sym.h +++ b/innobase/include/pars0sym.h @@ -122,7 +122,7 @@ struct sym_node_struct{ SYM_IMPLICIT_VAR, SYM_LIT, SYM_TABLE, SYM_CURSOR, ... */ - char* name; /* name of an id */ + const char* name; /* name of an id */ ulint name_len; /* id name length */ dict_table_t* table; /* table definition if a table id or a @@ -150,7 +150,7 @@ struct sym_tab_struct{ que_t* query_graph; /* query graph generated by the parser */ - char* sql_string; + const char* sql_string; /* SQL string to parse */ int string_len; /* SQL string length */ diff --git a/innobase/include/row0mysql.h b/innobase/include/row0mysql.h index 0b9f34dda1e..af6d8969cfc 100644 --- a/innobase/include/row0mysql.h +++ b/innobase/include/row0mysql.h @@ -316,15 +316,16 @@ fields than mentioned in the constraint. */ int row_table_add_foreign_constraints( /*==============================*/ - /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create statement where - foreign keys are declared like: + /* out: error code or DB_SUCCESS */ + trx_t* trx, /* in: transaction */ + const char* sql_string, /* in: table create statement where + foreign keys are declared like: FOREIGN KEY (a, b) REFERENCES table2(c, d), - table2 can be written also with the database - name before it: test.table2 */ - char* name); /* in: table full name in the normalized form - database_name/table_name */ + table2 can be written also with the + database name before it: test.table2 */ + const char* name); /* in: table full name in the + normalized form + database_name/table_name */ /************************************************************************* The master thread in srv0srv.c calls this regularly to drop tables which we must drop in background after queries to them have ended. Such lazy @@ -351,10 +352,10 @@ output by the master thread. */ int row_drop_table_for_mysql( /*=====================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx, /* in: transaction handle */ - ibool drop_db);/* in: TRUE=dropping whole database */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx, /* in: transaction handle */ + ibool drop_db);/* in: TRUE=dropping whole database */ /************************************************************************* Discards the tablespace of a table which stored in an .ibd file. Discarding @@ -382,9 +383,9 @@ discard ongoing operations. */ int row_discard_tablespace_for_mysql( /*=============================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx); /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx); /* in: transaction handle */ /********************************************************************* Imports a tablespace. The space id in the .ibd file must match the space id of the table in the data dictionary. */ @@ -392,28 +393,28 @@ of the table in the data dictionary. */ int row_import_tablespace_for_mysql( /*============================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx); /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx); /* in: transaction handle */ /************************************************************************* Drops a database for MySQL. */ int row_drop_database_for_mysql( /*========================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: database name which ends to '/' */ - trx_t* trx); /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: database name which ends to '/' */ + trx_t* trx); /* in: transaction handle */ /************************************************************************* Renames a table for MySQL. */ int row_rename_table_for_mysql( /*=======================*/ - /* out: error code or DB_SUCCESS */ - char* old_name, /* in: old table name */ - char* new_name, /* in: new table name */ - trx_t* trx); /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* old_name, /* in: old table name */ + const char* new_name, /* in: new table name */ + trx_t* trx); /* in: transaction handle */ /************************************************************************* Checks a table for corruption. */ diff --git a/innobase/include/row0sel.h b/innobase/include/row0sel.h index a35d588ad08..0be224eb255 100644 --- a/innobase/include/row0sel.h +++ b/innobase/include/row0sel.h @@ -144,11 +144,11 @@ consistent read result, or store it to the query cache. */ ibool row_search_check_if_query_cache_permitted( /*======================================*/ - /* out: TRUE if storing or retrieving from - the query cache is permitted */ - trx_t* trx, /* in: transaction object */ - char* norm_name); /* in: concatenation of database name, '/' - char, table name */ + /* out: TRUE if storing or retrieving + from the query cache is permitted */ + trx_t* trx, /* in: transaction object */ + const char* norm_name); /* in: concatenation of database name, + '/' char, table name */ /* A structure for caching column values for prefetched rows */ diff --git a/innobase/include/trx0roll.h b/innobase/include/trx0roll.h index 0d7126c9c57..6004551f456 100644 --- a/innobase/include/trx0roll.h +++ b/innobase/include/trx0roll.h @@ -193,7 +193,7 @@ trx_rollback_to_savepoint_for_mysql( DB_NO_SAVEPOINT, otherwise DB_SUCCESS */ trx_t* trx, /* in: transaction handle */ - char* savepoint_name, /* in: savepoint name */ + const char* savepoint_name, /* in: savepoint name */ ib_longlong* mysql_binlog_cache_pos);/* out: the MySQL binlog cache position corresponding to this savepoint; MySQL needs this @@ -211,7 +211,7 @@ trx_savepoint_for_mysql( /*====================*/ /* out: always DB_SUCCESS */ trx_t* trx, /* in: transaction handle */ - char* savepoint_name, /* in: savepoint name */ + const char* savepoint_name, /* in: savepoint name */ ib_longlong binlog_cache_pos); /* in: MySQL binlog cache position corresponding to this connection at the time of the diff --git a/innobase/include/trx0sys.h b/innobase/include/trx0sys.h index 9987955ec76..7d20455ffdf 100644 --- a/innobase/include/trx0sys.h +++ b/innobase/include/trx0sys.h @@ -258,7 +258,7 @@ replication has proceeded. */ void trx_sys_update_mysql_binlog_offset( /*===============================*/ - char* file_name,/* in: MySQL log file name */ + const char* file_name,/* in: MySQL log file name */ ib_longlong offset, /* in: position in that log file */ ulint field, /* in: offset of the MySQL log info field in the trx sys header */ diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 07d5e5a8215..a8c1df534da 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -315,7 +315,7 @@ struct trx_struct{ ulint magic_n; /* All the next fields are protected by the kernel mutex, except the undo logs which are protected by undo_mutex */ - char* op_info; /* English text describing the + const char* op_info; /* English text describing the current operation, or an empty string */ ulint type; /* TRX_USER, TRX_PURGE */ @@ -358,7 +358,7 @@ struct trx_struct{ char** mysql_query_str;/* pointer to the field in mysqld_thd which contains the pointer to the current SQL query string */ - char* mysql_log_file_name; + const char* mysql_log_file_name; /* if MySQL binlog is used, this field contains a pointer to the latest file name; this is NULL if binlog is not @@ -366,7 +366,7 @@ struct trx_struct{ ib_longlong mysql_log_offset;/* if MySQL binlog is used, this field contains the end offset of the binlog entry */ - char* mysql_master_log_file_name; + const char* mysql_master_log_file_name; /* if the database server is a MySQL replication slave, we have here the master binlog name up to which diff --git a/innobase/include/ut0rnd.h b/innobase/include/ut0rnd.h index c8ef0dd4001..aeec5d2f6eb 100644 --- a/innobase/include/ut0rnd.h +++ b/innobase/include/ut0rnd.h @@ -92,17 +92,17 @@ UNIV_INLINE ulint ut_fold_string( /*===========*/ - /* out: folded value */ - char* str); /* in: null-terminated string */ + /* out: folded value */ + const char* str); /* in: null-terminated string */ /***************************************************************** Folds a binary string. */ UNIV_INLINE ulint ut_fold_binary( /*===========*/ - /* out: folded value */ - byte* str, /* in: string of bytes */ - ulint len); /* in: length */ + /* out: folded value */ + const byte* str, /* in: string of bytes */ + ulint len); /* in: length */ /*************************************************************** Looks for a prime number slightly greater than the given argument. The prime is chosen so that it is not near any power of 2. */ diff --git a/innobase/include/ut0rnd.ic b/innobase/include/ut0rnd.ic index 5493c37404a..06d7012f60b 100644 --- a/innobase/include/ut0rnd.ic +++ b/innobase/include/ut0rnd.ic @@ -173,8 +173,8 @@ UNIV_INLINE ulint ut_fold_string( /*===========*/ - /* out: folded value */ - char* str) /* in: null-terminated string */ + /* out: folded value */ + const char* str) /* in: null-terminated string */ { #ifdef UNIV_DEBUG ulint i = 0; @@ -203,9 +203,9 @@ UNIV_INLINE ulint ut_fold_binary( /*===========*/ - /* out: folded value */ - byte* str, /* in: string of bytes */ - ulint len) /* in: length */ + /* out: folded value */ + const byte* str, /* in: string of bytes */ + ulint len) /* in: length */ { ulint i; ulint fold = 0; diff --git a/innobase/include/ut0ut.h b/innobase/include/ut0ut.h index 6c173f5cba9..04516535965 100644 --- a/innobase/include/ut0ut.h +++ b/innobase/include/ut0ut.h @@ -17,21 +17,6 @@ Created 1/20/1994 Heikki Tuuri typedef time_t ib_time_t; - -/************************************************************ -On the 64-bit Windows we substitute the format string -%l -> %I64 -because we define ulint as unsigned __int64 and lint as __int64 on Windows, -and both the Microsoft and Intel C compilers require the format string -%I64 in that case instead of %l. */ - -int -ut_printf( -/*======*/ - /* out: the number of characters written, or - negative in case of an error */ - const char* format, /* in: format of prints */ - ...); /* in: arguments to be printed */ /************************************************************ On the 64-bit Windows we substitute the format string %l -> %I64 diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 1a158372563..5f5060c7464 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -70,7 +70,7 @@ struct os_aio_slot_struct{ bytes */ ulint offset_high; /* 32 high bits of file offset */ os_file_t file; /* file where to read or write */ - char* name; /* file name or path */ + const char* name; /* file name or path */ ibool io_already_done;/* used only in simulated aio: TRUE if the physical i/o already made and only the slot message @@ -415,7 +415,7 @@ os_file_handle_error_no_exit( /* out: TRUE if we should retry the operation */ os_file_t file, /* in: file pointer */ - char* name, /* in: name of a file or NULL */ + const char* name, /* in: name of a file or NULL */ const char* operation)/* in: operation */ { ulint err; @@ -493,13 +493,15 @@ and '..' items at the start of the directory listing. */ os_file_dir_t os_file_opendir( /*============*/ - /* out: directory stream, NULL if error */ - char* dirname, /* in: directory name; it must not contain - a trailing '\' or '/' */ - ibool error_is_fatal) /* in: TRUE if we should treat an error as a - fatal error; if we try to open symlinks then - we do not wish a fatal error if it happens - not to be a directory */ + /* out: directory stream, NULL if + error */ + const char* dirname, /* in: directory name; it must not + contain a trailing '\' or '/' */ + ibool error_is_fatal) /* in: TRUE if we should treat an + error as a fatal error; if we try to + open symlinks then we do not wish a + fatal error if it happens not to be + a directory */ { os_file_dir_t dir; #ifdef __WIN__ @@ -585,7 +587,7 @@ os_file_readdir_next_file( /*======================*/ /* out: 0 if ok, -1 if error, 1 if at the end of the directory */ - char* dirname,/* in: directory name or path */ + const char* dirname,/* in: directory name or path */ os_file_dir_t dir, /* in: directory stream */ os_file_stat_t* info) /* in/out: buffer where the info is returned */ { @@ -704,12 +706,12 @@ fail_if_exists arguments is true. */ ibool os_file_create_directory( /*=====================*/ - /* out: TRUE if call succeeds, FALSE on - error */ - char* pathname, /* in: directory name as null-terminated - string */ - ibool fail_if_exists) /* in: if TRUE, pre-existing directory is - treated as an error. */ + /* out: TRUE if call succeeds, + FALSE on error */ + const char* pathname, /* in: directory name as + null-terminated string */ + ibool fail_if_exists) /* in: if TRUE, pre-existing directory + is treated as an error. */ { #ifdef __WIN__ BOOL rcode; @@ -746,18 +748,21 @@ A simple function to open or create a file. */ os_file_t os_file_create_simple( /*==================*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error), or - OS_FILE_CREATE_PATH if new file (if exists, error) and - subdirectories along its path are created (if needed)*/ - ulint access_type,/* in: OS_FILE_READ_ONLY or OS_FILE_READ_WRITE */ - ibool* success)/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file is + opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error), or + OS_FILE_CREATE_PATH if new file + (if exists, error) and subdirectories along + its path are created (if needed)*/ + ulint access_type,/* in: OS_FILE_READ_ONLY or + OS_FILE_READ_WRITE */ + ibool* success)/* out: TRUE if succeed, FALSE if error */ { #ifdef __WIN__ os_file_t file; @@ -882,18 +887,20 @@ A simple function to open or create a file. */ os_file_t os_file_create_simple_no_error_handling( /*====================================*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode,/* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error) */ - ulint access_type,/* in: OS_FILE_READ_ONLY, OS_FILE_READ_WRITE, or - OS_FILE_READ_ALLOW_DELETE; the last option is used by - a backup program reading the file */ - ibool* success)/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file + is opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error) */ + ulint access_type,/* in: OS_FILE_READ_ONLY, + OS_FILE_READ_WRITE, or + OS_FILE_READ_ALLOW_DELETE; the last option is + used by a backup program reading the file */ + ibool* success)/* out: TRUE if succeed, FALSE if error */ { #ifdef __WIN__ os_file_t file; @@ -991,25 +998,28 @@ Opens an existing file or creates a new. */ os_file_t os_file_create( /*===========*/ - /* out, own: handle to the file, not defined if error, - error number can be retrieved with - os_file_get_last_error */ - char* name, /* in: name of the file or path as a null-terminated - string */ - ulint create_mode, /* in: OS_FILE_OPEN if an existing file is opened - (if does not exist, error), or OS_FILE_CREATE if a new - file is created (if exists, error), OS_FILE_OVERWRITE - if a new is created or an old overwritten, - OS_FILE_OPEN_RAW, if a raw device or disk partition - should be opened */ - ulint purpose,/* in: OS_FILE_AIO, if asynchronous, non-buffered i/o - is desired, OS_FILE_NORMAL, if any normal file; - NOTE that it also depends on type, os_aio_.. and srv_.. - variables whether we really use async i/o or - unbuffered i/o: look in the function source code for - the exact rules */ - ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */ - ibool* success)/* out: TRUE if succeed, FALSE if error */ + /* out, own: handle to the file, not defined + if error, error number can be retrieved with + os_file_get_last_error */ + const char* name, /* in: name of the file or path as a + null-terminated string */ + ulint create_mode,/* in: OS_FILE_OPEN if an existing file + is opened (if does not exist, error), or + OS_FILE_CREATE if a new file is created + (if exists, error), + OS_FILE_OVERWRITE if a new file is created + or an old overwritten; + OS_FILE_OPEN_RAW, if a raw device or disk + partition should be opened */ + ulint purpose,/* in: OS_FILE_AIO, if asynchronous, + non-buffered i/o is desired, + OS_FILE_NORMAL, if any normal file; + NOTE that it also depends on type, os_aio_.. + and srv_.. variables whether we really use + async i/o or unbuffered i/o: look in the + function source code for the exact rules */ + ulint type, /* in: OS_DATA_FILE or OS_LOG_FILE */ + ibool* success)/* out: TRUE if succeed, FALSE if error */ { #ifdef __WIN__ os_file_t file; @@ -1202,8 +1212,8 @@ Deletes a file if it exists. The file has to be closed before calling this. */ ibool os_file_delete_if_exists( /*=====================*/ - /* out: TRUE if success */ - char* name) /* in: file path as a null-terminated string */ + /* out: TRUE if success */ + const char* name) /* in: file path as a null-terminated string */ { #ifdef __WIN__ BOOL ret; @@ -1263,8 +1273,8 @@ Deletes a file. The file has to be closed before calling this. */ ibool os_file_delete( /*===========*/ - /* out: TRUE if success */ - char* name) /* in: file path as a null-terminated string */ + /* out: TRUE if success */ + const char* name) /* in: file path as a null-terminated string */ { #ifdef __WIN__ BOOL ret; @@ -1327,9 +1337,9 @@ ibool os_file_rename( /*===========*/ /* out: TRUE if success */ - char* oldpath, /* in: old file path as a null-terminated + const char* oldpath,/* in: old file path as a null-terminated string */ - char* newpath) /* in: new file path */ + const char* newpath)/* in: new file path */ { #ifdef __WIN__ BOOL ret; @@ -1340,7 +1350,7 @@ os_file_rename( return(TRUE); } - os_file_handle_error(NULL, oldpath, "delete"); + os_file_handle_error(NULL, oldpath, "rename"); return(FALSE); #else @@ -1516,7 +1526,7 @@ ibool os_file_set_size( /*=============*/ /* out: TRUE if success */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ ulint size, /* in: least significant 32 bits of file @@ -1777,7 +1787,7 @@ os_file_pwrite( /*===========*/ /* out: number of bytes written, -1 if error */ os_file_t file, /* in: handle to a file */ - void* buf, /* in: buffer from where to write */ + const void* buf, /* in: buffer from where to write */ ulint n, /* in: number of bytes to write */ ulint offset, /* in: least significant 32 bits of file offset where to write */ @@ -2057,10 +2067,10 @@ os_file_write( /*==========*/ /* out: TRUE if request was successful, FALSE if fail */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ - void* buf, /* in: buffer from which to write */ + const void* buf, /* in: buffer from which to write */ ulint offset, /* in: least significant 32 bits of file offset where to write */ ulint offset_high, /* in: most significant 32 bits of @@ -2214,7 +2224,7 @@ ibool os_file_status( /*===========*/ /* out: TRUE if call succeeded */ - char* path, /* in: pathname of the file */ + const char* path, /* in: pathname of the file */ ibool* exists, /* out: TRUE if file exists */ os_file_type_t* type) /* out: type of the file (if it exists) */ { @@ -2319,7 +2329,7 @@ os_file_dirname( /*============*/ /* out, own: directory component of the pathname */ - char* path) /* in: pathname */ + const char* path) /* in: pathname */ { char* dir; int i, length, last_slash; @@ -2356,7 +2366,7 @@ os_file_create_subdirs_if_needed( /*=============================*/ /* out: TRUE if call succeeded FALSE otherwise */ - char* path) /* in: path name */ + const char* path) /* in: path name */ { char* subdir; static char rootdir[2] = { OS_FILE_PATH_SEPARATOR, 0 }; @@ -2753,7 +2763,7 @@ os_aio_array_reserve_slot( void* message2,/* in: message to be passed along with the aio operation */ os_file_t file, /* in: file handle */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ void* buf, /* in: buffer where to read or from which to write */ @@ -3000,7 +3010,7 @@ os_aio( because i/os are not actually handled until all have been posted: use with great caution! */ - char* name, /* in: name of the file or path as a + const char* name, /* in: name of the file or path as a null-terminated string */ os_file_t file, /* in: handle to a file */ void* buf, /* in: buffer where to read or from which @@ -3543,6 +3553,7 @@ consecutive_loop: if (n_consecutive == 1) { /* We can use the buffer of the i/o request */ combined_buf = slot->buf; + combined_buf2 = NULL; } else { combined_buf2 = ut_malloc(total_len + UNIV_PAGE_SIZE); @@ -3638,7 +3649,7 @@ consecutive_loop: } } - if (n_consecutive > 1) { + if (combined_buf2) { ut_free(combined_buf2); } diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index 7cbaf1f5123..c48c44a4c70 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -109,9 +109,9 @@ must be reset explicitly by calling sync_os_reset_event. */ os_event_t os_event_create( /*============*/ - /* out: the event handle */ - char* name) /* in: the name of the event, if NULL - the event is created without a name */ + /* out: the event handle */ + const char* name) /* in: the name of the event, if NULL + the event is created without a name */ { #ifdef __WIN__ os_event_t event; @@ -166,9 +166,9 @@ reset when a single thread is released. Works only in Windows. */ os_event_t os_event_create_auto( /*=================*/ - /* out: the event handle */ - char* name) /* in: the name of the event, if NULL - the event is created without a name */ + /* out: the event handle */ + const char* name) /* in: the name of the event, if NULL + the event is created without a name */ { os_event_t event; @@ -430,9 +430,9 @@ mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */ os_mutex_t os_mutex_create( /*============*/ - /* out: the mutex handle */ - char* name) /* in: the name of the mutex, if NULL - the mutex is created without a name */ + /* out: the mutex handle */ + const char* name) /* in: the name of the mutex, if NULL + the mutex is created without a name */ { #ifdef __WIN__ HANDLE mutex; diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c index 7e835d9ada1..12451b4d94d 100644 --- a/innobase/pars/pars0pars.c +++ b/innobase/pars/pars0pars.c @@ -1729,8 +1729,8 @@ Parses an SQL string returning the query graph. */ que_t* pars_sql( /*=====*/ - /* out, own: the query graph */ - char* str) /* in: SQL string */ + /* out, own: the query graph */ + const char* str) /* in: SQL string */ { sym_node_t* sym_node; mem_heap_t* heap; diff --git a/innobase/pars/pars0sym.c b/innobase/pars/pars0sym.c index 1a0608ed142..194e6677183 100644 --- a/innobase/pars/pars0sym.c +++ b/innobase/pars/pars0sym.c @@ -217,13 +217,10 @@ sym_tab_add_id( node->common.type = QUE_NODE_SYMBOL; - node->name = mem_heap_alloc(sym_tab->heap, len + 1); node->resolved = FALSE; node->indirection = NULL; - ut_memcpy(node->name, name, len); - node->name[len] = '\0'; - + node->name = mem_heap_strdupl(sym_tab->heap, name, len + 1); node->name_len = len; UT_LIST_ADD_LAST(sym_list, sym_tab->sym_list, node); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 154da11da58..61be3a7248e 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1686,15 +1686,16 @@ constraints which reference this table are ok. */ int row_table_add_foreign_constraints( /*==============================*/ - /* out: error code or DB_SUCCESS */ - trx_t* trx, /* in: transaction */ - char* sql_string, /* in: table create statement where - foreign keys are declared like: + /* out: error code or DB_SUCCESS */ + trx_t* trx, /* in: transaction */ + const char* sql_string, /* in: table create statement where + foreign keys are declared like: FOREIGN KEY (a, b) REFERENCES table2(c, d), - table2 can be written also with the database - name before it: test.table2 */ - char* name) /* in: table full name in the normalized form - database_name/table_name */ + table2 can be written also with the + database name before it: test.table2 */ + const char* name) /* in: table full name in the + normalized form + database_name/table_name */ { ulint err; @@ -1940,9 +1941,9 @@ discard ongoing operations. */ int row_discard_tablespace_for_mysql( /*=============================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx) /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx) /* in: transaction handle */ { dulint new_id; dict_table_t* table; @@ -2071,9 +2072,9 @@ of the table in the data dictionary. */ int row_import_tablespace_for_mysql( /*============================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx) /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx) /* in: transaction handle */ { dict_table_t* table; ibool success; @@ -2177,10 +2178,10 @@ the corresponding monitor output by the master thread. */ int row_drop_table_for_mysql( /*=====================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: table name */ - trx_t* trx, /* in: transaction handle */ - ibool drop_db)/* in: TRUE=dropping whole database */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: table name */ + trx_t* trx, /* in: transaction handle */ + ibool drop_db)/* in: TRUE=dropping whole database */ { dict_foreign_t* foreign; dict_table_t* table; @@ -2519,9 +2520,9 @@ Drops a database for MySQL. */ int row_drop_database_for_mysql( /*========================*/ - /* out: error code or DB_SUCCESS */ - char* name, /* in: database name which ends to '/' */ - trx_t* trx) /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* name, /* in: database name which ends to '/' */ + trx_t* trx) /* in: transaction handle */ { dict_table_t* table; char* table_name; @@ -2611,10 +2612,10 @@ Renames a table for MySQL. */ int row_rename_table_for_mysql( /*=======================*/ - /* out: error code or DB_SUCCESS */ - char* old_name, /* in: old table name */ - char* new_name, /* in: new table name */ - trx_t* trx) /* in: transaction handle */ + /* out: error code or DB_SUCCESS */ + const char* old_name, /* in: old table name */ + const char* new_name, /* in: new table name */ + trx_t* trx) /* in: transaction handle */ { dict_table_t* table; que_thr_t* thr; diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 47d61459d47..ff9b697c02f 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -3585,11 +3585,11 @@ consistent read result, or store it to the query cache. */ ibool row_search_check_if_query_cache_permitted( /*======================================*/ - /* out: TRUE if storing or retrieving from - the query cache is permitted */ - trx_t* trx, /* in: transaction object */ - char* norm_name) /* in: concatenation of database name, '/' - char, table name */ + /* out: TRUE if storing or retrieving + from the query cache is permitted */ + trx_t* trx, /* in: transaction object */ + const char* norm_name) /* in: concatenation of database name, + '/' char, table name */ { dict_table_t* table; ibool ret = FALSE; diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index 5c01a5371aa..e2e4f24b82e 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -200,7 +200,7 @@ trx_rollback_to_savepoint_for_mysql( DB_NO_SAVEPOINT, otherwise DB_SUCCESS */ trx_t* trx, /* in: transaction handle */ - char* savepoint_name, /* in: savepoint name */ + const char* savepoint_name, /* in: savepoint name */ ib_longlong* mysql_binlog_cache_pos) /* out: the MySQL binlog cache position corresponding to this savepoint; MySQL needs this @@ -265,7 +265,7 @@ trx_savepoint_for_mysql( /*====================*/ /* out: always DB_SUCCESS */ trx_t* trx, /* in: transaction handle */ - char* savepoint_name, /* in: savepoint name */ + const char* savepoint_name, /* in: savepoint name */ ib_longlong binlog_cache_pos) /* in: MySQL binlog cache position corresponding to this connection at the time of the diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index ef068d8d523..87abcbefa52 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -569,7 +569,7 @@ replication has proceeded. */ void trx_sys_update_mysql_binlog_offset( /*===============================*/ - char* file_name,/* in: MySQL log file name */ + const char* file_name,/* in: MySQL log file name */ ib_longlong offset, /* in: position in that log file */ ulint field, /* in: offset of the MySQL log info field in the trx sys header */ From e58b9c62fbcc165fa8fc8de9fbf8781d2af818d7 Mon Sep 17 00:00:00 2001 From: "marko@hundin.mysql.fi" <> Date: Mon, 17 May 2004 14:51:46 +0300 Subject: [PATCH 39/47] InnoDB cleanup: Remove unused function ut_printf() --- innobase/ut/ut0ut.c | 73 --------------------------------------------- 1 file changed, 73 deletions(-) diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index 21677e98318..cce98cf5644 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -36,79 +36,6 @@ because we define ulint as unsigned __int64 and lint as __int64 on Windows, and both the Microsoft and Intel C compilers require the format string %I64 in that case instead of %l. */ -int -ut_printf( -/*======*/ - /* out: the number of characters written, or - negative in case of an error */ - const char* format, /* in: format of prints */ - ...) /* in: arguments to be printed */ -{ - va_list args; - ulint len; - char* format_end; - char* newformat; - char* ptr; - char* newptr; - int ret; - char format_buf_in_stack[500]; - - len = strlen(format); - - if (len > 250) { - newformat = malloc(2 * len); - } else { - newformat = format_buf_in_stack; - } - - format_end = (char*)format + len; - - ptr = (char*)format; - newptr = newformat; - -#if defined(__WIN__) && (defined(WIN64) || defined(_WIN64)) - /* Replace %l with %I64 if it is not preceded with '\' */ - - while (ptr < format_end) { - if (*ptr == '%' && *(ptr + 1) == 'l' - && (ptr == format || *(ptr - 1) != '\\')) { - - memcpy(newptr, "%I64", 4); - ptr += 2; - newptr += 4; - } else { - *newptr = *ptr; - ptr++; - newptr++; - } - } - - *newptr = '\0'; - - ut_a(newptr < newformat + 2 * len); -#else - strcpy(newformat, format); -#endif - va_start(args, format); - - ret = vprintf((const char*)newformat, args); - - va_end(args); - - if (newformat != format_buf_in_stack) { - free(newformat); - } - - return(ret); -} - -/************************************************************ -On the 64-bit Windows we substitute the format string -%l -> %I64 -because we define ulint as unsigned __int64 and lint as __int64 on Windows, -and both the Microsoft and Intel C compilers require the format string -%I64 in that case instead of %l. */ - int ut_sprintf( /*=======*/ From 7961968adabb1275e24a8340e28b6d2227342c94 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 17 May 2004 18:45:59 +0200 Subject: [PATCH 40/47] current_thd is 0 if ha_resolve_by_name() is called when parsing command-line options --- sql/handler.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index f8eca1b93ef..9acd55db0b1 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -103,15 +103,16 @@ TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"", enum db_type ha_resolve_by_name(const char *name, uint namelen) { - if (!my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) { - return(enum db_type) current_thd->variables.table_type; + THD *thd=current_thd; + if (thd && !my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) { + return (enum db_type) thd->variables.table_type; } show_table_type_st *types; for (types= sys_table_types; types->type; types++) { if (!my_strcasecmp(&my_charset_latin1, name, types->type)) - return(enum db_type)types->db_type; + return (enum db_type) types->db_type; } return DB_TYPE_UNKNOWN; } From d9ec0f2b9043377ebe418d15943d85ead162c4df Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 18 May 2004 09:56:45 +0200 Subject: [PATCH 41/47] after merge fix --- client/mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index cf80a5594e4..14fb1e1f917 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2406,7 +2406,7 @@ com_shell(String *buffer, char *line __attribute__((unused))) char *shell_cmd; /* Skip space from line begin */ - while (isspace(*line)) + while (my_isspace(charset_info, *line)) line++; if (!(shell_cmd = strchr(line, ' '))) { From d9a6ff1125a1ddcf8a55c4cdac109872ae19eb48 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 18 May 2004 10:29:20 +0200 Subject: [PATCH 42/47] don't try to purge closed logs --- sql/sql_parse.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f2458068633..58b125b3ddc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4613,7 +4613,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, mysql_bin_log.new_file(1); mysql_slow_log.new_file(1); #ifdef HAVE_REPLICATION - if (expire_logs_days) + if (mysql_bin_log.is_open() && expire_logs_days) { long purge_time= time(0) - expire_logs_days*24*60*60; if (purge_time >= 0) From 3a7e3f061233cdc206e6d3fe797f7bcbfee209e1 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Tue, 18 May 2004 19:13:21 +0500 Subject: [PATCH 43/47] embedded library: fix for sending of parameters to stored procedure. using of methods like sint2korr() doesn't work on Bigendian machines --- sql/sql_prepare.cc | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 68da21018a0..a8e2cabe44b 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -256,8 +256,11 @@ void set_param_short(Item_param *param, uchar **pos, ulong len) #ifndef EMBEDDED_LIBRARY if (len < 2) return; -#endif int16 value= sint2korr(*pos); +#else + int16 value; + shortget(value, *pos); +#endif param->set_int(param->unsigned_flag ? (longlong) ((uint16) value) : (longlong) value); *pos+= 2; @@ -268,8 +271,11 @@ void set_param_int32(Item_param *param, uchar **pos, ulong len) #ifndef EMBEDDED_LIBRARY if (len < 4) return; -#endif int32 value= sint4korr(*pos); +#else + int32 value; + longget(value, *pos); +#endif param->set_int(param->unsigned_flag ? (longlong) ((uint32) value) : (longlong) value); *pos+= 4; @@ -280,9 +286,13 @@ void set_param_int64(Item_param *param, uchar **pos, ulong len) #ifndef EMBEDDED_LIBRARY if (len < 8) return; -#endif param->set_int((longlong)sint8korr(*pos)); *pos+= 8; +#else + longlong value; + longlongget(value, *pos); + param->set_int(value); +#endif } void set_param_float(Item_param *param, uchar **pos, ulong len) From 09f5f1edf2d96815c704e3d60330f796efb9f5dd Mon Sep 17 00:00:00 2001 From: "jani@a80-186-24-72.elisa-laajakaista.fi" <> Date: Tue, 18 May 2004 17:26:49 +0300 Subject: [PATCH 44/47] Fixed a bug in mysql-copy-right-2 script. As it was, it destroyed some ndb source files, such as ha_ndbcluster.cc --- Build-tools/mysql-copyright-2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Build-tools/mysql-copyright-2 b/Build-tools/mysql-copyright-2 index 447a2d7c164..e946ed217d1 100755 --- a/Build-tools/mysql-copyright-2 +++ b/Build-tools/mysql-copyright-2 @@ -93,7 +93,7 @@ sub add_copyright { $start_copyright="/* "; $line_copyright= " "; - $end_copyright= " */"; + $end_copyright= "*/"; } elsif ($ARGV =~ /-x86\.s$/) { From bab1dc82c7780c021142862bb23ba8b6c977bd92 Mon Sep 17 00:00:00 2001 From: "brian@brian-akers-computer.local" <> Date: Tue, 18 May 2004 09:54:36 -0700 Subject: [PATCH 45/47] Updating range_in_rows for the include file for ha_example (the main .cc file has already been updated). --- sql/examples/ha_example.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sql/examples/ha_example.h b/sql/examples/ha_example.h index ffc4f5b941c..2228f04284a 100644 --- a/sql/examples/ha_example.h +++ b/sql/examples/ha_example.h @@ -114,10 +114,8 @@ public: int reset(void); int external_lock(THD *thd, int lock_type); int delete_all_rows(void); - ha_rows records_in_range(int inx, const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + ha_rows records_in_range(uint inx, key_range *min_key, + key_range *max_key); int delete_table(const char *from); int rename_table(const char * from, const char * to); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); From 21f1bca7894a6879c5e530b0663dd5b0540d296c Mon Sep 17 00:00:00 2001 From: "monty@mysql.com" <> Date: Wed, 19 May 2004 05:09:10 +0300 Subject: [PATCH 46/47] Portability fixes Fixed wrong number of warnings/duplicates for machines with high-byte-first --- client/mysql.cc | 4 +--- client/mysqltest.c | 2 +- myisam/ft_nlq_search.c | 5 +++-- myisam/rt_test.c | 2 +- mysql-test/r/rpl_trunc_binlog.result | 2 +- mysql-test/t/rpl_trunc_binlog.test | 2 +- sql/sql_insert.cc | 4 ++-- strings/ctype-big5.c | 10 +++++----- strings/ctype-gbk.c | 8 ++++---- strings/ctype-mb.c | 2 +- strings/ctype-uca.c | 6 +++--- tests/client_test.c | 20 +++++++++++--------- 12 files changed, 34 insertions(+), 33 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index cf80a5594e4..e58790e5232 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1239,7 +1239,6 @@ static void fix_history(String *final_command) static int not_in_history(const char *line) { HIST_ENTRY *oldhist = history_get(history_length); - int num; if (oldhist == 0) return 1; @@ -1589,7 +1588,6 @@ static int com_server_help(String *buffer __attribute__((unused)), const char *server_cmd= buffer->ptr(); char cmd_buf[100]; MYSQL_RES *result; - MYSQL_FIELD *fields; int error; if (help_arg[0] != '\'') @@ -1615,7 +1613,7 @@ static int com_server_help(String *buffer __attribute__((unused)), { unsigned int num_fields= mysql_num_fields(result); my_ulonglong num_rows= mysql_num_rows(result); - fields= mysql_fetch_fields(result); + mysql_fetch_fields(result); if (num_fields==3 && num_rows==1) { if (!(cur= mysql_fetch_row(result))) diff --git a/client/mysqltest.c b/client/mysqltest.c index 2cd395a02b8..303473ef558 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -109,7 +109,7 @@ MYSQL_MANAGER* manager=0; static char **default_argv; static const char *load_default_groups[]= { "mysqltest","client",0 }; -static char line_buffer[MAX_DELIMITER], *line_buffer_pos= line_buffer;; +static char line_buffer[MAX_DELIMITER], *line_buffer_pos= line_buffer; static FILE* file_stack[MAX_INCLUDE_DEPTH]; static FILE** cur_file; diff --git a/myisam/ft_nlq_search.c b/myisam/ft_nlq_search.c index 9b42d51ab55..c9caf4f39af 100644 --- a/myisam/ft_nlq_search.c +++ b/myisam/ft_nlq_search.c @@ -90,8 +90,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) /* Skip rows inserted by current inserted */ for (r=_mi_search(info, keyinfo, keybuff, keylen, SEARCH_FIND, key_root) ; - (subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 && - !r && info->lastpos >= info->state->data_file_length ; + !r && + (subkeys=ft_sintXkorr(info->lastkey+info->lastkey_length-extra)) > 0 && + info->lastpos >= info->state->data_file_length ; r= _mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length, SEARCH_BIGGER, key_root)) ; diff --git a/myisam/rt_test.c b/myisam/rt_test.c index c1126c1939a..41cc56d4d78 100644 --- a/myisam/rt_test.c +++ b/myisam/rt_test.c @@ -39,7 +39,7 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused))) } -int run_test(const char *filename) +static int run_test(const char *filename) { MI_INFO *file; MI_UNIQUEDEF uniquedef; diff --git a/mysql-test/r/rpl_trunc_binlog.result b/mysql-test/r/rpl_trunc_binlog.result index ad0fb9e5022..085a2937584 100644 --- a/mysql-test/r/rpl_trunc_binlog.result +++ b/mysql-test/r/rpl_trunc_binlog.result @@ -10,4 +10,4 @@ reset slave; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 4 slave-relay-bin.000002 123 master-bin.000001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. A probable cause is that the master died while writing the transaction to its binary log. 0 79 326 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 4 slave-relay-bin.000002 123 master-bin.000001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. A probable cause is that the master died while writing the transaction to its binary log. 0 79 # None 0 No # diff --git a/mysql-test/t/rpl_trunc_binlog.test b/mysql-test/t/rpl_trunc_binlog.test index 32052af9184..2ade41ee96d 100644 --- a/mysql-test/t/rpl_trunc_binlog.test +++ b/mysql-test/t/rpl_trunc_binlog.test @@ -21,5 +21,5 @@ start slave; # can't sync_with_master so we must sleep sleep 3; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 23 # 33 # show slave status; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1bf95b8bded..3aa0e9511a7 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -411,7 +411,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); else sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) info.deleted+info.updated, (ulong) thd->cuted_fields); + (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); ::send_ok(thd,info.copied+info.deleted+info.updated,(ulonglong)id,buff); } free_underlaid_joins(thd, &thd->lex->select_lex); @@ -1582,7 +1582,7 @@ bool select_insert::send_eof() (ulong) (info.records - info.copied), (ulong) thd->cuted_fields); else sprintf(buff, ER(ER_INSERT_INFO), (ulong) info.records, - (ulong) info.deleted+info.updated, (ulong) thd->cuted_fields); + (ulong) (info.deleted+info.updated), (ulong) thd->cuted_fields); ::send_ok(thd,info.copied+info.deleted+info.updated,last_insert_id,buff); DBUG_RETURN(0); } diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 2bde29ecc47..ccb8d07e786 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -223,7 +223,7 @@ static uint16 big5strokexfrm(uint16 i) static int my_strnncoll_big5_internal(const uchar **a_res, const uchar **b_res, uint length) { - const char *a= *a_res, *b= *b_res; + const uchar *a= *a_res, *b= *b_res; while (length--) { @@ -236,10 +236,10 @@ static int my_strnncoll_big5_internal(const uchar **a_res, b+= 2; length--; } - else if (sort_order_big5[(uchar) *a++] != - sort_order_big5[(uchar) *b++]) - return ((int) sort_order_big5[(uchar) a[-1]] - - (int) sort_order_big5[(uchar) b[-1]]); + else if (sort_order_big5[*a++] != + sort_order_big5[*b++]) + return ((int) sort_order_big5[a[-1]] - + (int) sort_order_big5[b[-1]]); } *a_res= a; *b_res= b; diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 1990060e67b..577f8a33275 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -2585,7 +2585,7 @@ static uint16 gbksortorder(uint16 i) int my_strnncoll_gbk_internal(const uchar **a_res, const uchar **b_res, uint length) { - const char *a= *a_res, *b= *b_res; + const uchar *a= *a_res, *b= *b_res; uint a_char,b_char; while (length--) @@ -2601,9 +2601,9 @@ int my_strnncoll_gbk_internal(const uchar **a_res, const uchar **b_res, b+= 2; length--; } - else if (sort_order_gbk[(uchar) *a++] != sort_order_gbk[(uchar) *b++]) - return ((int) sort_order_gbk[(uchar) a[-1]] - - (int) sort_order_gbk[(uchar) b[-1]]); + else if (sort_order_gbk[*a++] != sort_order_gbk[*b++]) + return ((int) sort_order_gbk[a[-1]] - + (int) sort_order_gbk[b[-1]]); } *a_res= a; *b_res= b; diff --git a/strings/ctype-mb.c b/strings/ctype-mb.c index ed772a68845..9b02cd3b3da 100644 --- a/strings/ctype-mb.c +++ b/strings/ctype-mb.c @@ -283,7 +283,7 @@ uint my_well_formed_len_mb(CHARSET_INFO *cs, while (pos) { - if ((mblen= cs->cset->mb_wc(cs, &wc, b, e)) <0) + if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) b, (uchar*) e)) <0) break; b+= mblen; pos--; diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index ac805bf0a5a..72c28d92ca8 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -6750,8 +6750,8 @@ static int my_strnncollsp_uca(CHARSET_INFO *cs, int s_res; int t_res; - slen= cs->cset->lengthsp(cs, s, slen); - tlen= cs->cset->lengthsp(cs, t, tlen); + slen= cs->cset->lengthsp(cs, (char*) s, slen); + tlen= cs->cset->lengthsp(cs, (char*) t, tlen); my_uca_scanner_init(&sscanner, cs, s, slen); my_uca_scanner_init(&tscanner, cs, t, tlen); @@ -6796,7 +6796,7 @@ static void my_hash_sort_uca(CHARSET_INFO *cs, int s_res; my_uca_scanner scanner; - slen= cs->cset->lengthsp(cs, s, slen); + slen= cs->cset->lengthsp(cs, (char*) s, slen); my_uca_scanner_init(&scanner, cs, s, slen); while ((s_res= my_uca_scanner_next(&scanner)) >0) diff --git a/tests/client_test.c b/tests/client_test.c index c244274a2e7..871d09eb324 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -2400,7 +2400,8 @@ static void test_long_data_str() MYSQL_STMT *stmt; int rc, i; char data[255]; - long length, length1; + long length; + ulong length1; MYSQL_RES *result; MYSQL_BIND bind[2]; my_bool is_null[2]; @@ -2495,8 +2496,8 @@ static void test_long_data_str1() MYSQL_STMT *stmt; int rc, i; char data[255]; - long length, length1; - ulong max_blob_length, blob_length; + long length; + ulong max_blob_length, blob_length, length1; my_bool true_value; MYSQL_RES *result; MYSQL_BIND bind[2]; @@ -3084,7 +3085,7 @@ static void test_bind_result_ext() char szData[20], bData[20]; ulong szLength, bLength; MYSQL_BIND bind[8]; - long length[8]; + ulong length[8]; my_bool is_null[8]; myheader("test_bind_result_ext"); @@ -5376,7 +5377,7 @@ static void test_store_result2() MYSQL_STMT *stmt; int rc; int nData; - long length; + ulong length; MYSQL_BIND bind[1]; myheader("test_store_result2"); @@ -8094,7 +8095,7 @@ static void test_ts() MYSQL_TIME ts; MYSQL_RES *prep_res; char strts[30]; - long length; + ulong length; int rc, field_count; char name; @@ -8974,7 +8975,8 @@ static void test_multi() char *query; MYSQL_BIND bind[1]; int rc, i; - long param= 1, length= 1; + long param= 1; + ulong length= 1; myheader("test_multi"); bind[0].buffer_type= MYSQL_TYPE_LONG; @@ -9100,7 +9102,7 @@ static void test_bind_nagative() int rc; MYSQL_BIND bind[1]; long my_val = 0L; - long my_length = 0L; + ulong my_length = 0L; long my_null = 0L; myheader("test_insert_select"); @@ -9141,7 +9143,7 @@ static void test_derived() int rc, i; MYSQL_BIND bind[1]; long my_val = 0L; - long my_length = 0L; + ulong my_length = 0L; long my_null = 0L; const char *query= "select count(1) from (select f.id from t1 f where f.id=?) as x"; From ba749627ae3eef81fb0365d8d71f5371eaa8d0a2 Mon Sep 17 00:00:00 2001 From: "pem@mysql.comhem.se" <> Date: Wed, 19 May 2004 14:51:41 +0200 Subject: [PATCH 47/47] Fixed BUG#3709: SELECT INTO 1 FROM DUAL not parsed as expected Made the combination of INTO and FROM DUAL work, e.g. SELECT 1 INTO @x FROM DUAL. As a consequence, DUAL is made a reserved word. It would work to not have it reserved, but it was deemed to be confusing as a user defined table by the same name then must be qualified with a db (schema). --- sql/sql_yacc.yy | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index d7ef1fc8d7f..45e8e6e67e2 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1153,7 +1153,6 @@ merge_insert_types: opt_select_from: opt_limit_clause {} - | FROM DUAL_SYM {} | select_from select_lock_type; udf_func_type: @@ -2296,17 +2295,19 @@ select_part2: select_into: opt_limit_clause {} - | FROM DUAL_SYM /* oracle compatibility: oracle always requires FROM - clause, and DUAL is system table without fields. - Is "SELECT 1 FROM DUAL" any better than - "SELECT 1" ? Hmmm :) */ | into | select_from | into select_from | select_from into; select_from: - FROM join_table_list where_clause group_clause having_clause opt_order_clause opt_limit_clause procedure_clause; + FROM join_table_list where_clause group_clause having_clause + opt_order_clause opt_limit_clause procedure_clause + | FROM DUAL_SYM /* oracle compatibility: oracle always requires FROM + clause, and DUAL is system table without fields. + Is "SELECT 1 FROM DUAL" any better than + "SELECT 1" ? Hmmm :) */ + ; select_options: /* empty*/ @@ -4929,7 +4930,6 @@ keyword: | DIRECTORY_SYM {} | DISCARD {} | DO_SYM {} - | DUAL_SYM {} | DUMPFILE {} | DUPLICATE_SYM {} | DYNAMIC_SYM {}