From 07c2c4a67ca7d4469f9fb271fedece13845a3f25 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Thu, 1 May 2003 20:01:39 +0300 Subject: [PATCH 001/237] A fix for the crashing bug in mysql client program --- client/mysql.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/mysql.cc b/client/mysql.cc index a237561d83d..4ab97f1b3cf 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2593,6 +2593,8 @@ static void mysql_end_timer(ulong start_time,char *buff) static const char* construct_prompt() { //erase the old prompt + if (!mysql_get_host_info(&mysql)) + return processed_prompt.ptr(); processed_prompt.free(); //get the date struct time_t lclock = time(NULL); From ec4a0ee4771749ee382c3c3ccbdb3565d9fe848c Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Sat, 31 May 2003 21:35:20 +0300 Subject: [PATCH 002/237] several bug fixes --- include/my_global.h | 4 +++- mysys/charset.c | 1 + sql/sql_acl.cc | 15 ++++++++++++--- sql/sql_parse.cc | 7 ++++--- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 15495c60dd7..0bacb762421 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -263,8 +263,10 @@ C_MODE_END #endif #ifdef HAVE_ATOMIC_ADD #define __SMP__ -#define CONFIG_SMP #include +#ifndef CONFIG_SMP +#define CONFIG_SMP +#endif #endif #include /* Recommended by debian */ /* We need the following to go around a problem with openssl on solaris */ diff --git a/mysys/charset.c b/mysys/charset.c index 0a76cf86a54..6a64730571c 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -315,6 +315,7 @@ static CHARSET_INFO *add_charset(uint cs_number, const char *cs_name, myf flags) cs->to_lower=tmp_to_lower; cs->to_upper=tmp_to_upper; cs->sort_order=tmp_sort_order; + cs->strxfrm_multiply=cs->mbmaxlen=1; if (read_charset_file(cs_number, cs, flags)) return NULL; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f01248bb682..12ea3a94464 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2285,11 +2285,20 @@ int mysql_grant (THD *thd, const char *db, List &list, (!db ? rights : 0), revoke_grant, create_new_users))) result= -1; - else + else if (db) { - if (db && replace_db_table(tables[1].table, db, *Str, rights & DB_ACLS, - revoke_grant)) + ulong db_rights= rights & DB_ACLS; + if (db_rights == rights) + { + if (replace_db_table(tables[1].table, db, *Str, db_rights, + revoke_grant)) + result= -1; + } + else + { + net_printf(&thd->net,ER_WRONG_USAGE,"DB GRANT","GLOBAL PRIVILEGEY"); result= -1; + } } } VOID(pthread_mutex_unlock(&acl_cache->lock)); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d9060b4b26e..7ae963dab45 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -257,10 +257,11 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, db ? db : (char*) ""); thd->db_access=0; /* Don't allow user to connect if he has done too many queries */ - if ((ur.questions || ur.updates || ur.connections) && + if ((ur.questions || ur.updates || ur.connections || max_user_connections) && get_or_create_user_conn(thd,user,thd->host_or_ip,&ur)) return -1; - if (thd->user_connect && thd->user_connect->user_resources.connections && + if (thd->user_connect && ((thd->user_connect->user_resources.connections) || + max_user_connections) && check_for_max_user_connections(thd->user_connect)) return -1; if (db && db[0]) @@ -308,7 +309,7 @@ static int check_for_max_user_connections(USER_CONN *uc) DBUG_ENTER("check_for_max_user_connections"); if (max_user_connections && - (max_user_connections <= (uint) uc->connections)) + (max_user_connections < (uint) uc->connections)) { net_printf(&(current_thd->net),ER_TOO_MANY_USER_CONNECTIONS, uc->user); error=1; From d5bd302649ed2b5125841ff4ee4a8d24480305ff Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 3 Jun 2003 18:25:45 +0300 Subject: [PATCH 003/237] A fix for small stack overflow ... --- 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 7ae963dab45..2f9a7db5ef4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -196,7 +196,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, thd->db=0; thd->db_length=0; USER_RESOURCES ur; - char tmp_passwd[SCRAMBLE_LENGTH]; + char tmp_passwd[SCRAMBLE_LENGTH + 1]; if (passwd[0] && strlen(passwd) != SCRAMBLE_LENGTH) return 1; From 0058593c2d0a116c793968c7c0974f1903a62595 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Thu, 5 Jun 2003 17:02:00 +0200 Subject: [PATCH 004/237] Test for bug 578. And a comment in slave.cc. --- mysql-test/r/lock_tables_lost_commit.result | 8 ++++++++ .../t/lock_tables_lost_commit-master.opt | 1 + mysql-test/t/lock_tables_lost_commit.test | 18 +++++++++++++++++ sql/slave.cc | 20 +++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 mysql-test/r/lock_tables_lost_commit.result create mode 100644 mysql-test/t/lock_tables_lost_commit-master.opt create mode 100644 mysql-test/t/lock_tables_lost_commit.test diff --git a/mysql-test/r/lock_tables_lost_commit.result b/mysql-test/r/lock_tables_lost_commit.result new file mode 100644 index 00000000000..ccf56793f45 --- /dev/null +++ b/mysql-test/r/lock_tables_lost_commit.result @@ -0,0 +1,8 @@ +drop table if exists t1; +create table t1(a int) type=innodb; +lock tables t1 write; +insert into t1 values(10); +select * from t1; +a +10 +drop table t1; diff --git a/mysql-test/t/lock_tables_lost_commit-master.opt b/mysql-test/t/lock_tables_lost_commit-master.opt new file mode 100644 index 00000000000..d357a51cb27 --- /dev/null +++ b/mysql-test/t/lock_tables_lost_commit-master.opt @@ -0,0 +1 @@ +--binlog-ignore-db=test innodb \ No newline at end of file diff --git a/mysql-test/t/lock_tables_lost_commit.test b/mysql-test/t/lock_tables_lost_commit.test new file mode 100644 index 00000000000..a12ee7369cb --- /dev/null +++ b/mysql-test/t/lock_tables_lost_commit.test @@ -0,0 +1,18 @@ +# This is a test for bug 578 + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +drop table if exists t1; +create table t1(a int) type=innodb; +lock tables t1 write; +insert into t1 values(10); +disconnect con1; + +connection con2; +# The bug was that, because of the LOCK TABLES, the handler "forgot" to commit, +# and the other commit when we write to the binlog was not done because of +# binlog-ignore-db +select * from t1; +drop table t1; diff --git a/sql/slave.cc b/sql/slave.cc index c2762dbd6f4..bead4323b0c 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1186,6 +1186,26 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) strmov(strcend(tmp,'.'),"-relay-bin"); opt_relay_logname=my_strdup(tmp,MYF(MY_WME)); } + + /* + The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE. It is + notable that the last kilobytes of it (8 kB for example) may live in memory, + not on disk (depending on what the thread using it does). While this is + efficient, it has a side-effect one must know: + the size of the relay log on disk (displayed by 'ls -l' on Unix) can be a + few kilobytes less than one would expect by doing SHOW SLAVE STATUS; this + happens when only the IO thread is started (not the SQL thread). The + "missing" kilobytes are in memory, are preserved during 'STOP SLAVE; START + SLAVE IO_THREAD', and are flushed to disk when the slave's mysqld stops. So + this does not cause any bug. Example of how disk size grows by leaps: + + Read_Master_Log_Pos: 7811 -rw-rw---- 1 guilhem qq 4 Jun 5 16:19 gbichot2-relay-bin.002 + ...later... + Read_Master_Log_Pos: 9744 -rw-rw---- 1 guilhem qq 8192 Jun 5 16:27 gbichot2-relay-bin.002 + + See how 4 is less than 7811 and 8192 is less than 9744. + */ + if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname, "-relay-bin", opt_relaylog_index_name, LOG_BIN, 1 /* read_append cache */, From 255a40c2f055be869e59efd5b4beff2d832ffbae Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Fri, 6 Jun 2003 04:18:58 +0300 Subject: [PATCH 005/237] sql_yacc.yy, sql_parse.cc, sql_lex.h, mysqld.cc, lex.h: Add syntax SAVEPOINT id and ROLLBACK TO SAVEPOINT id. This is compatible with DB2 and Oracle but not with SQL Server. Savepoints do not do anything yet, this is just parsing. --- sql/lex.h | 1 + sql/mysqld.cc | 1 + sql/sql_lex.h | 4 +++- sql/sql_parse.cc | 3 +++ sql/sql_yacc.yy | 24 +++++++++++++++++++++--- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/sql/lex.h b/sql/lex.h index d9a84dd25b4..3bbe1da185e 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -309,6 +309,7 @@ static SYMBOL symbols[] = { { "ROLLUP", SYM(ROLLUP_SYM),0,0}, { "ROW", SYM(ROW_SYM),0,0}, { "ROWS", SYM(ROWS_SYM),0,0}, + { "SAVEPOINT", SYM(SAVEPOINT_SYM),0,0}, { "SECOND", SYM(SECOND_SYM),0,0}, { "SELECT", SYM(SELECT_SYM),0,0}, { "SERIALIZABLE", SYM(SERIALIZABLE_SYM),0,0}, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 315931094c2..7883b9700ad 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4021,6 +4021,7 @@ struct show_var_st status_vars[]= { {"Com_restore_table", (char*) (com_stat+(uint) SQLCOM_RESTORE_TABLE),SHOW_LONG}, {"Com_revoke", (char*) (com_stat+(uint) SQLCOM_REVOKE),SHOW_LONG}, {"Com_rollback", (char*) (com_stat+(uint) SQLCOM_ROLLBACK),SHOW_LONG}, + {"Com_savepoint", (char*) (com_stat+(uint) SQLCOM_SAVEPOINT),SHOW_LONG}, {"Com_select", (char*) (com_stat+(uint) SQLCOM_SELECT),SHOW_LONG}, {"Com_set_option", (char*) (com_stat+(uint) SQLCOM_SET_OPTION),SHOW_LONG}, {"Com_show_binlog_events", (char*) (com_stat+(uint) SQLCOM_SHOW_BINLOG_EVENTS),SHOW_LONG}, diff --git a/sql/sql_lex.h b/sql/sql_lex.h index a905871e629..7d931399782 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -54,7 +54,8 @@ enum enum_sql_command { SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, - SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, + SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SAVEPOINT, + SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER, SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE, SQLCOM_RESET, SQLCOM_PURGE, SQLCOM_SHOW_BINLOGS, @@ -154,6 +155,7 @@ typedef struct st_lex SQL_LIST proc_list, auxilliary_table_list; TYPELIB *interval; create_field *last_field; + char* savepoint_name; // Transaction savepoint id Item *default_value; CONVERT *convert_set; CONVERT *thd_convert_set; // Set with SET CHAR SET diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b06a48f9045..7447ba44e76 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2533,6 +2533,9 @@ mysql_execute_command(void) res= -1; thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); break; + case SQLCOM_SAVEPOINT: + send_ok(&thd->net); + break; default: /* Impossible */ send_ok(&thd->net); break; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index b0c81d6f6b0..2ef0992cdf7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -135,6 +135,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token RESET_SYM %token ROLLBACK_SYM %token ROLLUP_SYM +%token SAVEPOINT_SYM %token SELECT_SYM %token SHOW %token SLAVE @@ -573,7 +574,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); query verb_clause create change select do drop insert replace insert2 insert_values update delete truncate rename show describe load alter optimize flush - reset purge begin commit rollback slave master_def master_defs + reset purge begin commit rollback savepoint + slave master_def master_defs repair restore backup analyze check start field_list field_list_item field_spec kill column_def key_def select_item_list select_item values_list no_braces @@ -649,6 +651,7 @@ verb_clause: | restore | revoke | rollback + | savepoint | select | set | slave @@ -3382,6 +3385,7 @@ keyword: | ROWS_SYM {} | ROW_FORMAT_SYM {} | ROW_SYM {} + | SAVEPOINT_SYM {} | SECOND_SYM {} | SERIALIZABLE_SYM {} | SESSION_SYM {} @@ -3915,8 +3919,22 @@ commit: COMMIT_SYM { Lex->sql_command = SQLCOM_COMMIT;}; rollback: - ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK;}; - + ROLLBACK_SYM + { + Lex->sql_command = SQLCOM_ROLLBACK; + Lex->savepoint_name = NULL; + } + | ROLLBACK_SYM TO_SYM SAVEPOINT_SYM ident + { + Lex->sql_command = SQLCOM_ROLLBACK; + Lex->savepoint_name = $4.str; + }; +savepoint: + SAVEPOINT_SYM ident + { + Lex->sql_command = SQLCOM_SAVEPOINT; + Lex->savepoint_name = $2.str; + }; /* ** UNIONS : glue selects together From c1a60342f6320158fd5233611839749e04ab2cc7 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 6 Jun 2003 13:52:15 +0200 Subject: [PATCH 006/237] -- already approved; it would be nice if it goes into 3.23.57 -- Fix for bug 254 : the first Start_log_event after server startup will have created=now(), whereas the next ones (FLUSH LOGS, auto rotation) will have created=0. Before this, it was always now(). This way, slaves >=4.0.14 will know when they must drop stale temp tables or not. The next task is now modify 4.0.14 to implement this. --- sql/log.cc | 16 +++++++++++++--- sql/log_event.h | 9 +++++++++ sql/sql_class.h | 2 +- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index d189f1f1fe3..69957c5c97c 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -157,7 +157,7 @@ void MYSQL_LOG::close_index() } void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, - const char *new_name) + const char *new_name, bool null_created) { MY_STAT tmp_stat; char buff[512]; @@ -230,8 +230,10 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, if ((do_magic && my_b_write(&log_file, (byte*) BINLOG_MAGIC, 4)) || open_index(O_APPEND | O_RDWR | O_CREAT)) goto err; - Start_log_event s; bool error; + Start_log_event s; + if (null_created) + s.created= 0; s.write(&log_file); flush_io_cache(&log_file); pthread_mutex_lock(&LOCK_index); @@ -548,7 +550,15 @@ void MYSQL_LOG::new_file(bool inside_mutex) strmov(new_name, old_name); // Reopen old file name name=0; close(); - open(old_name, log_type, new_name); + /* + new_file() is only used for rotation (in FLUSH LOGS or because size > + max_binlog_size). + If this is a binary log, the Start_log_event at the beginning of + the new file should have created=0 (to distinguish with the Start_log_event + written at server startup, which should trigger temp tables deletion on + >=4.0.14 slaves). + */ + open(old_name, log_type, new_name, 1); my_free(old_name,MYF(0)); last_time=query_start=0; write_error=0; diff --git a/sql/log_event.h b/sql/log_event.h index 68696442490..bb1c9260e21 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -327,6 +327,15 @@ extern char server_version[SERVER_VERSION_LENGTH]; class Start_log_event: public Log_event { public: + /* + If this event is at the start of the first binary log since server startup + 'created' should be the timestamp when the event (and the binary log) was + created. + In the other case (i.e. this event is at the start of a binary log created + by FLUSH LOGS or automatic rotation), 'created' should be 0. + This "trick" is used by MySQL >=4.0.14 slaves to know if they must drop the + stale temporary tables or not. + */ time_t created; uint16 binlog_version; char server_version[50]; diff --git a/sql/sql_class.h b/sql/sql_class.h index d9497907926..8abf87c4cda 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -73,7 +73,7 @@ public: void set_index_file_name(const char* index_file_name = 0); void init(enum_log_type log_type_arg); void open(const char *log_name,enum_log_type log_type, - const char *new_name=0); + const char *new_name=0, bool null_created= 0); void new_file(bool inside_mutex = 0); bool open_index(int options); void close_index(); From 1dccfd055d2d246edb35d2b30ed11f38e8d1a905 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 6 Jun 2003 14:13:26 +0200 Subject: [PATCH 007/237] In Start_log_event::print, don't print "created 1970 etc" if created == 0. Otherwise, we'll get questions from users about this curious 1970. --- sql/log_event.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 1c9c48e2d93..62d6bef3a51 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -302,9 +302,13 @@ void Start_log_event::print(FILE* file, bool short_form, char* last_db) return; print_header(file); - fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version, + fprintf(file, "\tStart: binlog v %d, server v %s", binlog_version, server_version); - print_timestamp(file, &created); + if (created) + { + fprintf(file, " created "); + print_timestamp(file, &created); + } fputc('\n', file); fflush(file); } From 60fb005e5e0ed7c15be4132a24f703b321dd41a0 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 6 Jun 2003 16:41:28 +0200 Subject: [PATCH 008/237] Fix for bug 254 : we now make a distinction between if the master is < 3.23.57, 3.23 && >=57, and 4.x (before the 2 3.23 were one). This is because in 3.23.57 we have a way to distinguish between a Start_log_event written at server startup and one written at FLUSH LOGS, so we have a way to know if the slave must drop old temp tables or not. Change: mi->old_format was bool, now it's enum (to handle 3 cases). However, functions which had 'bool old_format' as an argument have their prototypes unchanged, because the old old_format == 0 now corresponds to the enum value BINLOG_FORMAT_CURRENT which is equal to 0, so boolean tests are left untouched. The only case were we use mi->old_format as an enum instead of casting it implicitly to a bool, is in Start_log_event::exec_event, where we want to distinguish between the 3 possible enum values. --- sql/log_event.cc | 40 ++++++++++++++++++++++++++++------------ sql/slave.cc | 20 ++++++++++++++++++-- sql/slave.h | 11 ++++++++--- 3 files changed, 54 insertions(+), 17 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 369ef940af2..ff968babcf0 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2000,11 +2000,8 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, IMPLEMENTATION - To handle the case where the master died without a stop event, - we clean up all temporary tables + locks that we got. - However, we don't clean temporary tables if the master was 3.23 - (this is because a 3.23 master writes a Start_log_event at every - binlog rotation; if we were not careful we would remove temp tables - on the slave when FLUSH LOGS is issued on the master). + we clean up all temporary tables that we got, if we are sure we + can (see below). TODO - Remove all active user locks @@ -2015,18 +2012,37 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, int Start_log_event::exec_event(struct st_relay_log_info* rli) { - if (!rli->mi->old_format) - { + + switch (rli->mi->old_format) { + case BINLOG_FORMAT_CURRENT : /* - If 4.0 master, all temporary tables have been deleted on the master; - if 3.23 master, this is far from sure. + This is 4.x, so a Start_log_event is only at master startup, + so we are sure the master has restarted and cleared his temp tables. */ close_temporary_tables(thd); - /* - If we have old format, load_tmpdir is cleaned up by the I/O thread - */ cleanup_load_tmpdir(); + break; + /* + Now the older formats; in that case load_tmpdir is cleaned up by the I/O + thread. + */ + case BINLOG_FORMAT_323_LESS_57 : + /* + Cannot distinguish a Start_log_event generated at master startup and + one generated by master FLUSH LOGS, so cannot be sure temp tables + have to be dropped. So do nothing. + */ + break; + case BINLOG_FORMAT_323_GEQ_57 : + /* Can distinguish, based on the value of 'created' */ + if (created) /* this was generated at master startup*/ + close_temporary_tables(thd); + break; + default : + /* this case is impossible */ + return 1; } + return Log_event::exec_event(rli); } diff --git a/sql/slave.cc b/sql/slave.cc index bead4323b0c..cc0fa26027f 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -962,13 +962,19 @@ static int check_master_version(MYSQL* mysql, MASTER_INFO* mi) { const char* errmsg= 0; + /* + Note the following switch will bug when we have MySQL branch 30 ;) + */ switch (*mysql->server_version) { case '3': - mi->old_format = 1; + mi->old_format = + (strncmp(mysql->server_version, "3.23.57", 7) < 0) /* < .57 */ ? + BINLOG_FORMAT_323_LESS_57 : + BINLOG_FORMAT_323_GEQ_57 ; break; case '4': case '5': - mi->old_format = 0; + mi->old_format = BINLOG_FORMAT_CURRENT; break; default: errmsg = "Master reported unrecognized MySQL version"; @@ -1204,6 +1210,16 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) Read_Master_Log_Pos: 9744 -rw-rw---- 1 guilhem qq 8192 Jun 5 16:27 gbichot2-relay-bin.002 See how 4 is less than 7811 and 8192 is less than 9744. + + WARNING: this is risky because the slave can stay like this for a long time; + then if it has a power failure, master.info says the I/O thread has read + until 9744 while the relay-log contains only until 8192 (the in-memory part + from 8192 to 9744 has been lost), so the SQL slave thread will miss some + events, silently breaking replication. + Ideally we would like to flush master.info only when we know that the relay + log has no in-memory tail. + Note that the above problem may arise only when only the IO thread is + started, which is unlikely. */ if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname, diff --git a/sql/slave.h b/sql/slave.h index 8832302056d..66000f45e69 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -35,6 +35,11 @@ extern my_bool opt_log_slave_updates; extern ulonglong relay_log_space_limit; struct st_master_info; +enum enum_binlog_formats { + BINLOG_FORMAT_CURRENT=0, /* 0 is important for easy 'if (mi->old_format)' */ + BINLOG_FORMAT_323_LESS_57, + BINLOG_FORMAT_323_GEQ_57 }; + /* TODO: this needs to be redone, but for now it does not matter since we do not have multi-master yet. @@ -266,15 +271,15 @@ typedef struct st_master_info int events_till_abort; #endif bool inited; - bool old_format; /* master binlog is in 3.23 format */ + enum enum_binlog_formats old_format; /* master binlog is in 3.23 format */ volatile bool abort_slave, slave_running; volatile ulong slave_run_id; bool ignore_stop_event; st_master_info() - :fd(-1), io_thd(0), inited(0), old_format(0),abort_slave(0), - slave_running(0), slave_run_id(0) + :fd(-1), io_thd(0), inited(0), old_format(BINLOG_FORMAT_CURRENT), + abort_slave(0),slave_running(0), slave_run_id(0) { host[0] = 0; user[0] = 0; password[0] = 0; bzero(&file, sizeof(file)); From a7d65ce3b98954e512606b7666cf5b901e881777 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sat, 7 Jun 2003 10:25:56 +0300 Subject: [PATCH 009/237] page0page.c: Fix a bug: a race condition could cause that the first B-tree page splits would get a corrupt page directory, whic often results in the assertion in page_dir_find_slot(); found with a test of 3000 startups/shutdowns; it is not clear that this would have caused any corruption which users have reported --- innobase/page/page0page.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index f3f6776bf13..af1ccb92016 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -406,12 +406,6 @@ page_create( rec_set_next_offs(infimum_rec, (ulint)(supremum_rec - page)); rec_set_next_offs(supremum_rec, 0); - - if (page_template == NULL) { - page_template = mem_alloc(UNIV_PAGE_SIZE); - - ut_memcpy(page_template, page, UNIV_PAGE_SIZE); - } return(page); } From 39660b1f2445bbacd5d21c77420b8bda74c5bef8 Mon Sep 17 00:00:00 2001 From: "miguel@sartre.local" <> Date: Sun, 8 Jun 2003 02:53:41 -0400 Subject: [PATCH 010/237] Translation updated --- BitKeeper/etc/logging_ok | 1 + sql/share/spanish/errmsg.txt | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 003708e2944..2d9cd004d0f 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -14,6 +14,7 @@ lenz@mysql.com miguel@hegel.br miguel@hegel.local miguel@light.local +miguel@sartre.local monty@bitch.mysql.fi monty@donna.mysql.fi monty@hundin.mysql.fi diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index b9c88873106..089bc13e8d3 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -212,11 +212,11 @@ "Bloqueos de actualización no pueden ser adqueridos durante una transición READ UNCOMMITTED", "DROP DATABASE no permitido mientras un thread está ejerciendo un bloqueo de lectura global", "CREATE DATABASE no permitido mientras un thread está ejerciendo un bloqueo de lectura global", -"Wrong arguments to %s", -"%-.32s@%-.64s is not allowed to create new users", -"Incorrect table definition; All MERGE tables must be in the same database", -"Deadlock found when trying to get lock; Try restarting transaction", -"The used table type doesn't support FULLTEXT indexes", -"Cannot add foreign key constraint", -"Cannot add a child row: a foreign key constraint fails", -"Cannot delete a parent row: a foreign key constraint fails", +"Argumentos errados para %s", +"%-.32s@%-.64s no es permitido para crear nuevos usuarios", +"Incorrecta definición de la tabla; Todas las tablas MERGE deben estar en el mismo banco de datos", +"Encontrado deadlock cuando tentando obtener el bloqueo; Tente recomenzar la transición", +"El tipo de tabla usada no soporta índices FULLTEXT", +"No puede adicionar clave extranjera constraint", +"No puede adicionar una línea hijo: falla de clave extranjera constraint", +"No puede deletar una línea padre: falla de clave extranjera constraint", From d640ff4a974d5bbb2751c28cfa6db3a53e69bd90 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Tue, 10 Jun 2003 21:42:29 +0300 Subject: [PATCH 011/237] Don't install signal handler for SIGINT by default Added option --gdb Free memory used by replicate_xxx and binglog_xxx options --- mysql-test/mysql-test-run.sh | 6 +++++ mysys/thr_alarm.c | 9 ++++---- sql/mysql_priv.h | 5 +++++ sql/mysqld.cc | 43 +++++++++++++++++++++++++++--------- sql/repl_failsafe.cc | 1 + sql/sql_list.cc | 15 +++++++++++++ 6 files changed, 65 insertions(+), 14 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index ab4a5354dae..3fe9070bbd6 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -319,11 +319,15 @@ while test $# -gt 0; do $ECHO "Note: you will get more meaningful output on a source distribution compiled with debugging option when running tests with --client-gdb option" fi DO_CLIENT_GDB=1 + EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --gdb" + EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb" ;; --manual-gdb ) DO_GDB=1 MANUAL_GDB=1 USE_RUNNING_SERVER="" + EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --gdb" + EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb" ;; --ddd ) if [ x$BINARY_DIST = x1 ] ; then @@ -331,6 +335,8 @@ while test $# -gt 0; do fi DO_DDD=1 USE_RUNNING_SERVER="" + EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --gdb" + EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb" ;; --valgrind) VALGRIND="valgrind --alignment=8 --leak-check=yes --num-callers=16" diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 7a845e3eb00..2a16eeec215 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -220,8 +220,7 @@ void thr_end_alarm(thr_alarm_t *alarmed) { ALARM *alarm_data; sigset_t old_mask; - uint i; - my_bool found=0; + uint i, found=0; DBUG_ENTER("thr_end_alarm"); pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask); @@ -235,11 +234,13 @@ void thr_end_alarm(thr_alarm_t *alarmed) queue_remove(&alarm_queue,i),MYF(0); if (alarm_data->malloced) my_free((gptr) alarm_data,MYF(0)); - found=1; + found++; +#ifndef DBUG_OFF break; +#endif } } - DBUG_ASSERT(!*alarmed || found); + DBUG_ASSERT(!*alarmed || found == 1); if (!found) { if (*alarmed) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9cf18b53669..702db98748a 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -140,6 +140,7 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define TEST_NO_EXTRA 128 #define TEST_CORE_ON_SIGNAL 256 /* Give core if signal */ #define TEST_NO_STACKTRACE 512 +#define TEST_SIGINT 1024 /* Allow sigint on threads */ /* options for select set by the yacc parser (stored in lex->options) */ #define SELECT_DISTINCT 1 @@ -820,6 +821,10 @@ Item *get_system_var(enum_var_type var_type, LEX_STRING name); /* log.cc */ bool flush_error_log(void); +/* sql_list.cc */ +void free_list(I_List *list); +void free_list(I_List *list); + /* Some inline functions for more speed */ inline bool add_item_to_list(Item *item) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7883b9700ad..ca98ab96710 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -285,7 +285,7 @@ char log_error_file[FN_REFLEN]; bool opt_log, opt_update_log, opt_bin_log, opt_slow_log; bool opt_error_log= IF_WIN(1,0); bool opt_disable_networking=0, opt_skip_show_db=0; -my_bool opt_enable_named_pipe= 0; +my_bool opt_enable_named_pipe= 0, opt_debugging= 0; my_bool opt_local_infile, opt_external_locking, opt_slave_compressed_protocol; uint delay_key_write_options= (uint) DELAY_KEY_WRITE_ON; @@ -387,7 +387,7 @@ bool opt_using_transactions, using_update_log; bool volatile abort_loop, select_thread_in_use, signal_thread_in_use; bool volatile ready_to_exit, shutdown_in_progress, grant_option; ulong refresh_version=1L,flush_version=1L; /* Increments on each reload */ -ulong query_id=1L,long_query_count,aborted_threads, +ulong query_id=1L,long_query_count,aborted_threads, killed_threads, aborted_connects,delayed_insert_timeout,delayed_insert_limit, delayed_queue_size,delayed_insert_threads,delayed_insert_writes, delayed_rows_in_use,delayed_insert_errors,flush_time, thread_created; @@ -919,6 +919,12 @@ void clean_up(bool print_message) bitmap_free(&temp_pool); free_max_user_conn(); end_slave_list(); + free_list(&replicate_do_db); + free_list(&replicate_ignore_db); + free_list(&binlog_do_db); + free_list(&binlog_ignore_db); + free_list(&replicate_rewrite_db); + #ifdef HAVE_OPENSSL if (ssl_acceptor_fd) my_free((gptr) ssl_acceptor_fd, MYF(MY_ALLOW_ZERO_PTR)); @@ -1273,7 +1279,10 @@ extern "C" sig_handler end_thread_signal(int sig __attribute__((unused))) THD *thd=current_thd; DBUG_ENTER("end_thread_signal"); if (thd && ! thd->bootstrap) + { + statistic_increment(killed_threads, &LOCK_status); end_thread(thd,0); + } DBUG_VOID_RETURN; /* purecov: deadcode */ } @@ -1592,7 +1601,8 @@ static void init_signals(void) struct sigaction sa; DBUG_ENTER("init_signals"); - sigset(THR_KILL_SIGNAL,end_thread_signal); + if (test_flags & TEST_SIGINT) + sigset(THR_KILL_SIGNAL,end_thread_signal); sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called! if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL)) @@ -1651,7 +1661,8 @@ static void init_signals(void) sigaddset(&set,SIGTSTP); #endif sigaddset(&set,THR_SERVER_ALARM); - sigdelset(&set,THR_KILL_SIGNAL); // May be SIGINT + if (test_flags & TEST_SIGINT) + sigdelset(&set,THR_KILL_SIGNAL); // May be SIGINT sigdelset(&set,THR_CLIENT_ALARM); // For alarms sigprocmask(SIG_SETMASK,&set,NULL); pthread_sigmask(SIG_SETMASK,&set,NULL); @@ -1707,9 +1718,12 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) */ init_thr_alarm(max_connections+max_insert_delayed_threads+10); #if SIGINT != THR_KILL_SIGNAL - (void) sigemptyset(&set); // Setup up SIGINT for debug - (void) sigaddset(&set,SIGINT); // For debugging - (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL); + if (test_flags & TEST_SIGINT) + { + (void) sigemptyset(&set); // Setup up SIGINT for debug + (void) sigaddset(&set,SIGINT); // For debugging + (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL); + } #endif (void) sigemptyset(&set); // Setup up SIGINT for debug #ifdef USE_ONE_SIGNAL_HAND @@ -2715,6 +2729,7 @@ static void create_new_thread(THD *thd) thread_count--; thd->killed=1; // Safety (void) pthread_mutex_unlock(&LOCK_thread_count); + statistic_increment(aborted_connects,&LOCK_status); net_printf(net,ER_CANT_CREATE_THREAD,error); (void) pthread_mutex_lock(&LOCK_thread_count); close_connection(net,0,0); @@ -3145,7 +3160,7 @@ enum options { OPT_QUERY_CACHE_TYPE, OPT_RECORD_BUFFER, OPT_RECORD_RND_BUFFER, OPT_RELAY_LOG_SPACE_LIMIT, OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME, - OPT_READONLY, + OPT_READONLY, OPT_DEBUGGING, OPT_SORT_BUFFER, OPT_TABLE_CACHE, OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE, OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK, @@ -3277,6 +3292,10 @@ struct my_option my_long_options[] = GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, /* We must always support the next option to make scripts like mysqltest easier to do */ + {"gdb", OPT_DEBUGGING, + "Set up signals usable for debugging", + (gptr*) &opt_debugging, (gptr*) &opt_debugging, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH, @@ -3469,8 +3488,6 @@ Does nothing yet.", OPT_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection.", (gptr*) &mysql_port, (gptr*) &mysql_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"reckless-slave", OPT_RECKLESS_SLAVE, "For debugging", 0, 0, 0, GET_NO_ARG, - NO_ARG, 0, 0, 0, 0, 0, 0}, {"replicate-do-db", OPT_REPLICATE_DO_DB, "Tells the slave thread to restrict replication to the specified database. To specify more than one database, use the directive multiple times, once for each database. Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.%.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -4717,6 +4734,12 @@ static void get_options(int argc,char **argv) have_symlink=SHOW_OPTION_DISABLED; } #endif + if (opt_debugging) + { + /* Allow break with SIGINT, no core or stack trace */ + test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE; + test_flags&= ~TEST_CORE_ON_SIGNAL; + } /* Set global MyISAM variables from delay_key_write_options */ fix_delay_key_write((THD*) 0, OPT_GLOBAL); diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 8ed002ca649..1552b3994e9 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -71,6 +71,7 @@ static int init_failsafe_rpl_thread(THD* thd) if (init_thr_lock() || thd->store_globals()) { close_connection(&thd->net,ER_OUT_OF_RESOURCES); // is this needed? + statistic_increment(aborted_connects,&LOCK_status); end_thread(thd,0); DBUG_RETURN(-1); } diff --git a/sql/sql_list.cc b/sql/sql_list.cc index 1124605ca24..c99cfb8c918 100644 --- a/sql/sql_list.cc +++ b/sql/sql_list.cc @@ -22,3 +22,18 @@ #include "mysql_priv.h" list_node end_of_list; + +void free_list(I_List *list) +{ + i_string_pair *tmp; + while ((tmp= list->get())) + delete tmp; +} + + +void free_list(I_List *list) +{ + i_string *tmp; + while ((tmp= list->get())) + delete tmp; +} From 96c8d91a0cc36d3b66c1c08e82527ebe04d447d2 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Tue, 10 Jun 2003 23:29:49 +0200 Subject: [PATCH 012/237] More error messages. This is intended to help debugging; presently I have a support issue with an unclear message which can have N reasons for appearing. This should help us know at which point it failed, and get the errno when my_open was involved (as the reason for the unclear message is often a permission problem). RESET SLAVE resets last_error and last_errno in SHOW SLAVE STATUS (without this, rpl_loaddata.test, which is expected to generate an error in last_error, influenced rpl_log_pos.test). A small test update. Added STOP SLAVE to mysql-test-run to get rid of several stupid error messages which are printed while the master restarts and the slave attempts/manages to connect to it and sends it nonsense binlog requests. --- mysql-test/mysql-test-run.sh | 16 +++++ mysql-test/r/rpl000018.result | 1 + mysql-test/t/rpl000018.test | 2 + sql/slave.cc | 119 ++++++++++++++++++++++++++-------- sql/sql_repl.cc | 15 ++++- 5 files changed, 125 insertions(+), 28 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index ab4a5354dae..c688380b402 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -1064,6 +1064,16 @@ stop_slave () fi } +stop_slave_threads () +{ + eval "this_slave_running=\$SLAVE$1_RUNNING" + slave_ident="slave$1" + if [ x$this_slave_running = x1 ] + then + $MYSQLADMIN --no-defaults -uroot --socket=$MYSQL_TMP_DIR/$slave_ident.sock stop-slave > /dev/null 2>&1 + fi +} + stop_master () { if [ x$MASTER_RUNNING = x1 ] @@ -1157,6 +1167,12 @@ run_testcase () return fi + # Stop all slave threads, so that we don't have useless reconnection attempts + # and error messages in case the slave and master servers restart. + stop_slave_threads + stop_slave_threads 1 + stop_slave_threads 2 + if [ -z "$USE_RUNNING_SERVER" ] ; then if [ -f $master_opt_file ] ; diff --git a/mysql-test/r/rpl000018.result b/mysql-test/r/rpl000018.result index ba51406bba0..282c1e492a1 100644 --- a/mysql-test/r/rpl000018.result +++ b/mysql-test/r/rpl000018.result @@ -1,3 +1,4 @@ +reset master; reset slave; slave start; show master logs; diff --git a/mysql-test/t/rpl000018.test b/mysql-test/t/rpl000018.test index 291b482b912..3bd5fd0ef09 100644 --- a/mysql-test/t/rpl000018.test +++ b/mysql-test/t/rpl000018.test @@ -6,6 +6,8 @@ require_manager; connect (master,localhost,root,,test,0,master.sock); connect (slave,localhost,root,,test,0,slave.sock); +connection master; +reset master; server_stop master; server_start master; connection slave; diff --git a/sql/slave.cc b/sql/slave.cc index cc0fa26027f..d2bc5b2f758 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -115,6 +115,8 @@ int init_slave() { DBUG_ENTER("init_slave"); + /* This is called when mysqld starts */ + /* TODO: re-write this to interate through the list of files for multi-master @@ -126,11 +128,16 @@ int init_slave() If master_host is specified, create the master_info file if it doesn't exists. */ - if (!active_mi || - init_master_info(active_mi,master_info_file,relay_log_info_file, + if (!active_mi) + { + sql_print_error("Failed to allocate memory for the master info structure"); + goto err; + } + + if(init_master_info(active_mi,master_info_file,relay_log_info_file, !master_host)) { - sql_print_error("Note: Failed to initialized master info"); + sql_print_error("Failed to initialize the master info structure"); goto err; } @@ -150,7 +157,7 @@ int init_slave() relay_log_info_file, SLAVE_IO | SLAVE_SQL)) { - sql_print_error("Warning: Can't create threads to handle slave"); + sql_print_error("Failed to create slave threads"); goto err; } } @@ -1226,7 +1233,10 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) "-relay-bin", opt_relaylog_index_name, LOG_BIN, 1 /* read_append cache */, 1 /* no auto events */)) + { + sql_print_error("Failed in open_log() called from init_relay_log_info()"); DBUG_RETURN(1); + } /* if file does not exist */ if (access(fname,F_OK)) @@ -1237,10 +1247,18 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) */ if (info_fd >= 0) my_close(info_fd, MYF(MY_WME)); - if ((info_fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 || - init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0, - MYF(MY_WME))) + if ((info_fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0) { + sql_print_error("Failed to create a new relay log info file (\ +file '%s', errno %d)", fname, my_errno); + msg= current_thd->net.last_error; + goto err; + } + if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0, + MYF(MY_WME))) + { + sql_print_error("Failed to create a cache on relay log info file (\ +file '%s')", fname); msg= current_thd->net.last_error; goto err; } @@ -1248,7 +1266,11 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) /* Init relay log with first entry in the relay index file */ if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */, &msg)) + { + sql_print_error("Failed to open the relay log (relay_log_name='FIRST', \ +relay_log_pos=4"); goto err; + } rli->master_log_name[0]= 0; rli->master_log_pos= 0; rli->info_fd= info_fd; @@ -1257,18 +1279,33 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) { if (info_fd >= 0) reinit_io_cache(&rli->info_file, READ_CACHE, 0L,0,0); - else if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 || - init_io_cache(&rli->info_file, info_fd, - IO_SIZE*2, READ_CACHE, 0L, 0, MYF(MY_WME))) + else { - if (info_fd >= 0) - my_close(info_fd, MYF(0)); - rli->info_fd= -1; - rli->relay_log.close(1); - pthread_mutex_unlock(&rli->data_lock); - DBUG_RETURN(1); + int error=0; + if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0) + { + sql_print_error("Failed to open the existing relay log info file (\ +file '%s', errno %d)", fname, my_errno); + error= 1; + } + else if (init_io_cache(&rli->info_file, info_fd, + IO_SIZE*2, READ_CACHE, 0L, 0, MYF(MY_WME))) + { + sql_print_error("Failed to create a cache on relay log info file (\ +file '%s')", fname); + error= 1; + } + if (error) + { + if (info_fd >= 0) + my_close(info_fd, MYF(0)); + rli->info_fd= -1; + rli->relay_log.close(1); + pthread_mutex_unlock(&rli->data_lock); + DBUG_RETURN(1); + } } - + rli->info_fd = info_fd; int relay_log_pos, master_log_pos; if (init_strvar_from_file(rli->relay_log_name, @@ -1292,7 +1329,12 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) rli->relay_log_pos, 0 /* no data lock*/, &msg)) + { + char llbuf[22]; + sql_print_error("Failed to open the relay log (relay_log_name='%s', \ +relay_log_pos=%s", rli->relay_log_name, llstr(rli->relay_log_pos, llbuf)); goto err; + } } DBUG_ASSERT(rli->relay_log_pos >= BIN_LOG_HEADER_SIZE); DBUG_ASSERT(my_b_tell(rli->cur_log) == rli->relay_log_pos); @@ -1301,7 +1343,8 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) before flush_relay_log_info */ reinit_io_cache(&rli->info_file, WRITE_CACHE,0L,0,1); - error= flush_relay_log_info(rli); + if ((error= flush_relay_log_info(rli))) + sql_print_error("Failed to flush relay log info file"); if (count_relay_log_space(rli)) { msg="Error counting relay log space"; @@ -1404,6 +1447,8 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, pthread_mutex_lock(&mi->data_lock); fd = mi->fd; + + /* does master.info exist ? */ if (access(fname,F_OK)) { @@ -1418,10 +1463,19 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, */ if (fd >= 0) my_close(fd, MYF(MY_WME)); - if ((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 || - init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0, - MYF(MY_WME))) + if ((fd = my_open(fname, O_CREAT|O_RDWR|O_BINARY, MYF(MY_WME))) < 0 ) + { + sql_print_error("Failed to create a new master info file (\ +file '%s', errno %d)", fname, my_errno); goto err; + } + if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L,0, + MYF(MY_WME))) + { + sql_print_error("Failed to create a cache on master info file (\ +file '%s')", fname); + goto err; + } mi->master_log_name[0] = 0; mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number @@ -1440,10 +1494,22 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, { if (fd >= 0) reinit_io_cache(&mi->file, READ_CACHE, 0L,0,0); - else if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 || - init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L, - 0, MYF(MY_WME))) - goto err; + else + { + if ((fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0 ) + { + sql_print_error("Failed to open the existing master info file (\ +file '%s', errno %d)", fname, my_errno); + goto err; + } + if (init_io_cache(&mi->file, fd, IO_SIZE*2, READ_CACHE, 0L, + 0, MYF(MY_WME))) + { + sql_print_error("Failed to create a cache on master info file (\ +file '%s')", fname); + goto err; + } + } mi->fd = fd; int port, connect_retry, master_log_pos; @@ -1484,7 +1550,8 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, mi->inited = 1; // now change cache READ -> WRITE - must do this before flush_master_info reinit_io_cache(&mi->file, WRITE_CACHE,0L,0,1); - error=test(flush_master_info(mi)); + if ((error=test(flush_master_info(mi)))) + sql_print_error("Failed to flush master info file"); pthread_mutex_unlock(&mi->data_lock); DBUG_RETURN(error); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index ca993c053a1..a651d8002fd 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -159,10 +159,18 @@ File open_binlog(IO_CACHE *log, const char *log_file_name, File file; DBUG_ENTER("open_binlog"); - if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0 || - init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0, + if ((file = my_open(log_file_name, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0) + { + sql_print_error("Failed to open log (\ +file '%s', errno %d)", log_file_name, my_errno); + *errmsg = "Could not open log file"; // This will not be sent + goto err; + } + if (init_io_cache(log, file, IO_SIZE*2, READ_CACHE, 0, 0, MYF(MY_WME | MY_DONT_CHECK_FILESIZE))) { + sql_print_error("Failed to create a cache on log (\ +file '%s')", log_file_name); *errmsg = "Could not open log file"; // This will not be sent goto err; } @@ -743,6 +751,9 @@ int reset_slave(THD *thd, MASTER_INFO* mi) //Clear master's log coordinates (only for good display of SHOW SLAVE STATUS) mi->master_log_name[0]= 0; mi->master_log_pos= BIN_LOG_HEADER_SIZE; + //Clear the errors displayed by SHOW SLAVE STATUS + mi->rli.last_slave_error[0]=0; + mi->rli.last_slave_errno=0; //close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0 end_master_info(mi); //and delete these two files From 90543684b4ad445562e267e430aa14cfffb477c7 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 11 Jun 2003 13:38:02 +0200 Subject: [PATCH 013/237] - fixed a path to init script in RPM spec file (/sbin/init.d is obsolete) --- support-files/mysql.spec.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 06ba2d63f45..6cc33866efd 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -327,7 +327,7 @@ install -m755 $MBD/support-files/mysql.server $RBR/etc/init.d/mysql # Create a symlink "rcmysql", pointing to the init.script. SuSE users # will appreciate that, as all services usually offer this. -ln -s ../../sbin/init.d/mysql $RPM_BUILD_ROOT/usr/sbin/rcmysql +ln -s ../../etc/init.d/mysql $RPM_BUILD_ROOT/usr/sbin/rcmysql # Create symbolic compatibility link safe_mysqld -> mysqld_safe # (safe_mysqld will be gone in MySQL 4.1) From 2daa5643d3c9a5218f75a47476fa5624ad477cfe Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 11 Jun 2003 13:40:20 +0200 Subject: [PATCH 014/237] - applied patch to mysql_explain_log.sh provided by Dennis Haney to accept --socket option (Bug #592) --- scripts/mysql_explain_log.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/mysql_explain_log.sh b/scripts/mysql_explain_log.sh index c4a4ef21568..973d9e8a363 100644 --- a/scripts/mysql_explain_log.sh +++ b/scripts/mysql_explain_log.sh @@ -14,12 +14,14 @@ $Param->{host}=''; $Param->{user}=''; $Param->{password}=''; $Param->{PrintError}=0; +$Param->{socket}=''; if (!GetOptions ('date|d:i' => \$Param->{ViewDate}, 'host|h:s' => \$Param->{host}, 'user|u:s' => \$Param->{user}, 'password|p:s' => \$Param->{password}, 'printerror|e:s' => \$Param->{PrintError}, + 'socket|s:s' => \$Param->{socket}, )) { ShowOptions(); } @@ -50,7 +52,7 @@ else { #print "Date=$Param->{ViewDate}, host=$Param->{host}, user=$Param->{user}, password=$Param->{password}\n"; - $Param->{dbh}=DBI->connect("DBI:mysql:host=$Param->{host}",$Param->{user},$Param->{password},{PrintError=>0}); + $Param->{dbh}=DBI->connect("DBI:mysql:host=$Param->{host}".($Param->{socket}?";mysql_socket=$Param->{socket}":""),$Param->{user},$Param->{password},{PrintError=>0}); if (DBI::err()) { print "Error: " . DBI::errstr() . "\n"; } @@ -313,6 +315,8 @@ Usage: $0 [OPTIONS] < LOGFILE -u=USERNAME --password=PASSWORD password of db-user -p=PASSWORD +--socket=SOCKET mysqld socket file to connect +-s=SOCKET Read logfile from STDIN an try to EXPLAIN all SELECT statements. All UPDATE statements are rewritten to an EXPLAIN SELECT statement. The results of the EXPLAIN statement are collected and counted. All results with type=ALL are collected in an separete list. Results are printed to STDOUT. @@ -344,7 +348,7 @@ Then add indices to avoid table scans and remove those which aren't used. =head1 USAGE -explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw] < logfile +explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw] [--socket=/path/to/socket] < logfile --date=YYMMDD select only entrys of date @@ -362,14 +366,19 @@ explain_log.pl [--date=YYMMDD] --host=dbhost] [--user=dbuser] [--password=dbpw] -p=PASSWORD +--socket=SOCKET change path to the socket + +-s=SOCKET + =head1 EXAMPLE explain_log.pl --host=localhost --user=foo --password=bar < /var/lib/mysql/mobile.log -=head1 AUTHOR +=head1 AUTHORS Stefan Nitz Jan Willamowius , http://www.mobile.de + Dennis Haney (Added socket support) =head1 RECRUITING From 2401227ceb6c1645a837bed9b1c4bc77f725766e Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 11 Jun 2003 15:41:03 +0300 Subject: [PATCH 015/237] os0file.c: Prevent on Windows starting of two mysqld instances on SAME InnoDB files: that could cause severe database corruption --- innobase/os/os0file.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 4008f8f6c76..46474d3576a 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -386,9 +386,9 @@ try_again: file = CreateFile(name, access, - FILE_SHARE_READ | FILE_SHARE_WRITE, - /* file can be read and written - also by other processes */ + FILE_SHARE_READ, + /* file can be read also by other + processes */ NULL, /* default security attributes */ create_flag, attributes, @@ -526,9 +526,14 @@ try_again: file = CreateFile(name, GENERIC_READ | GENERIC_WRITE, /* read and write access */ - FILE_SHARE_READ | FILE_SHARE_WRITE, - /* file can be read and written - also by other processes */ + FILE_SHARE_READ,/* File can be read also by other + processes; we must give the read + permission because of ibbackup. We do + not give the write permission to + others because if one would succeed to + start 2 instances of mysqld on the + SAME files, that could cause severe + database corruption! */ NULL, /* default security attributes */ create_flag, attributes, From 8fea9b451abeb0fbcc6001e3823590e6bb57e245 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Wed, 11 Jun 2003 20:09:37 +0500 Subject: [PATCH 016/237] Bugfix for #614 Item_extract needs special implementation for eq(). Item_func::eq doesn't work correctly because we have to compare Item_extract::int_type parameters also We need to propagate this to 4.1 --- BitKeeper/etc/logging_ok | 1 + sql/item_timefunc.cc | 16 ++++++++++++++++ sql/item_timefunc.h | 1 + 3 files changed, 18 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 4617e9d697b..092b6f3f2a5 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -24,6 +24,7 @@ heikki@donna.mysql.fi heikki@hundin.mysql.fi heikki@rescue. heikki@work.mysql.com +hf@deer.(none) hf@deer.mysql.r18.ru hf@genie.(none) igor@hundin.mysql.fi diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 6a95c15a226..84e7a44ac61 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1137,6 +1137,22 @@ longlong Item_extract::val_int() return 0; // Impossible } +bool Item_extract::eq(const Item *item, bool binary_cmp) const +{ + if (this == item) + return 1; + if (item->type() != FUNC_ITEM || + func_name() != ((Item_func*)item)->func_name()) + return 0; + + Item_extract* ie= (Item_extract*)item; + if (ie->int_type != int_type) + return 0; + + if (!args[0]->eq(ie->args[0], binary_cmp)) + return 0; + return 1; +} void Item_typecast::print(String *str) { diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 0ca2a36609d..e04e24627d9 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -422,6 +422,7 @@ class Item_extract :public Item_int_func longlong val_int(); const char *func_name() const { return "extract"; } void fix_length_and_dec(); + bool eq(const Item *item, bool binary_cmp) const; unsigned int size_of() { return sizeof(*this);} }; From db088dc477d8ed59d7123a45f66da4c39dd57e57 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Wed, 11 Jun 2003 22:07:23 +0500 Subject: [PATCH 017/237] test case for bug #614 --- mysql-test/r/func_time.result | 3 +++ mysql-test/t/func_time.test | 2 ++ 2 files changed, 5 insertions(+) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 2941352c776..06c0be86667 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -329,6 +329,9 @@ insert into t1 values ('2001-01-12 12:23:40'); select ctime, hour(ctime) from t1; ctime hour(ctime) 2001-01-12 12:23:40 12 +select ctime from t1 where extract(MONTH FROM ctime) = 1 AND extract(YEAR FROM ctime) = 2001; +ctime +2001-01-12 12:23:40 drop table t1; create table t1 (id int); create table t2 (id int, date date); diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index dd589ff2e66..3057729ab96 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -123,6 +123,8 @@ select extract(MONTH FROM "2001-02-00"); create table t1 (ctime varchar(20)); insert into t1 values ('2001-01-12 12:23:40'); select ctime, hour(ctime) from t1; +# test bug 614 (multiple extracts in where) +select ctime from t1 where extract(MONTH FROM ctime) = 1 AND extract(YEAR FROM ctime) = 2001; drop table t1; # From 63df5f7cb71ce01fa5f3dfc1a072cc57e8aab32b Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Thu, 12 Jun 2003 13:52:24 +0200 Subject: [PATCH 018/237] - applied patch for mysqld_safe from Christian Hammers to be able to define a different niceness level in my.cnf (Bug #627) --- scripts/mysqld_safe.sh | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index e400c27b84c..626e04b1579 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -70,6 +70,7 @@ parse_arguments() { MYSQLD="mysqld" fi ;; + --nice=*) niceness=`echo "$arg" | sed -e "s;--nice=;;"` ;; *) if test -n "$pick_args" then @@ -110,6 +111,7 @@ fi MYSQL_UNIX_PORT=${MYSQL_UNIX_PORT:-@MYSQL_UNIX_ADDR@} MYSQL_TCP_PORT=${MYSQL_TCP_PORT:-@MYSQL_TCP_PORT@} user=@MYSQLD_USER@ +niceness=0 # Use the mysqld-max binary by default if the user doesn't specify a binary if test -x $ledir/mysqld-max @@ -167,7 +169,12 @@ export MYSQL_UNIX_PORT export MYSQL_TCP_PORT -NOHUP_NICENESS="nohup" +if test $niceness -eq 0 +then + NOHUP_NICENESS="nohup" +else + NOHUP_NICENESS="nohup nice -$niceness" +fi # Using nice with no args to get the niceness level is GNU-specific. # This check could be extended for other operating systems (e.g., @@ -198,8 +205,10 @@ then nice --$nice_value_diff echo testing > /dev/null 2>&1 then # nohup increases the priority (bad), and we are permitted - # to lower the priority - NOHUP_NICENESS="nice --$nice_value_diff nohup" + # to lower the priority with respect to the value the user + # might have been given + niceness=`expr $niceness - $nice_value_diff` + NOHUP_NICENESS="nice -$niceness nohup" fi fi else From a79bdf2ee75fa48b34cd4736b49ea91197afaeae Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Thu, 12 Jun 2003 16:25:26 +0300 Subject: [PATCH 019/237] Indentation --- mysys/safemalloc.c | 247 ++++++++++++++++++++++----------------------- 1 file changed, 121 insertions(+), 126 deletions(-) diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 9cbb178edb4..42cff1e5069 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -69,7 +69,7 @@ #include "my_static.h" #include "mysys_err.h" -ulonglong safemalloc_mem_limit = ~(ulonglong)0; +ulonglong safemalloc_mem_limit= ~(ulonglong)0; #define pNext tInt._pNext #define pPrev tInt._pPrev @@ -84,7 +84,7 @@ ulonglong safemalloc_mem_limit = ~(ulonglong)0; the linked list of blocks so that _sanity() will not fuss when it is not supposed to */ -static int sf_malloc_tampered = 0; +static int sf_malloc_tampered= 0; #endif @@ -92,11 +92,11 @@ static int sf_malloc_tampered = 0; static int check_ptr(const char *where, byte *ptr, const char *sFile, uint uLine); -static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine); +static int _checkchunk(struct irem *pRec, const char *sFile, uint uLine); /* - Note: both these refer to the NEW'ed data only. They do not include - malloc() roundoff or the extra space required by the remember + Note: We only fill up the allocated block. This do not include + malloc() roundoff or the extra space required by the irem structures. */ @@ -127,90 +127,85 @@ static int _checkchunk(struct remember *pRec, const char *sFile, uint uLine); /* Allocate some memory. */ -gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags) +gptr _mymalloc(uint uSize, const char *sFile, uint uLine, myf MyFlags) { - struct remember *pTmp; - DBUG_ENTER("_mymalloc"); - DBUG_PRINT("enter",("Size: %u",uSize)); + struct remember *pTmp; + DBUG_ENTER("_mymalloc"); + DBUG_PRINT("enter",("Size: %u",uSize)); + if (!sf_malloc_quick) + (void) _sanity (sFile, uLine); - if (!sf_malloc_quick) - (void) _sanity (sFile, uLine); - - if (uSize + lCurMemory > safemalloc_mem_limit) - pTmp = 0; - else + if (uSize + lCurMemory > safemalloc_mem_limit) + pTmp= 0; + else + { + /* Allocate the physical memory */ + pTmp= (struct remember *) malloc (ALIGN_SIZE(sizeof(struct irem)) + + sf_malloc_prehunc + + uSize + /* size requested */ + 4 + /* overrun mark */ + sf_malloc_endhunc + ); + } + /* Check if there isn't anymore memory avaiable */ + if (pTmp == NULL) + { + if (MyFlags & MY_FAE) + error_handler_hook=fatal_error_handler_hook; + if (MyFlags & (MY_FAE+MY_WME)) { - /* Allocate the physical memory */ - pTmp = (struct remember *) malloc ( - ALIGN_SIZE(sizeof(struct irem)) /* remember data */ - + sf_malloc_prehunc - + uSize /* size requested */ - + 4 /* overrun mark */ - + sf_malloc_endhunc - ); - } - /* Check if there isn't anymore memory avaiable */ - if (pTmp == NULL) - { - if (MyFlags & MY_FAE) - error_handler_hook=fatal_error_handler_hook; - if (MyFlags & (MY_FAE+MY_WME)) - { - char buff[SC_MAXWIDTH]; - my_errno=errno; - sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile); - my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); - sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)", - uSize, (uSize + 1023L) / 1024L, - lMaxMemory, (lMaxMemory + 1023L) / 1024L); - my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); - } - DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'", - lMaxMemory,uLine, sFile)); - if (MyFlags & MY_FAE) - exit(1); - DBUG_RETURN ((gptr) NULL); + char buff[SC_MAXWIDTH]; + my_errno=errno; + sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile); + my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); + sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)", + uSize, (uSize + 1023L) / 1024L, + lMaxMemory, (lMaxMemory + 1023L) / 1024L); + my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); } + DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'", + lMaxMemory,uLine, sFile)); + if (MyFlags & MY_FAE) + exit(1); + DBUG_RETURN ((gptr) NULL); + } - /* Fill up the structure */ - *((long*) ((char*) &pTmp -> lSpecialValue+sf_malloc_prehunc)) = MAGICKEY; - pTmp -> aData[uSize + sf_malloc_prehunc+0] = MAGICEND0; - pTmp -> aData[uSize + sf_malloc_prehunc+1] = MAGICEND1; - pTmp -> aData[uSize + sf_malloc_prehunc+2] = MAGICEND2; - pTmp -> aData[uSize + sf_malloc_prehunc+3] = MAGICEND3; - pTmp -> sFileName = (my_string) sFile; - pTmp -> uLineNum = uLine; - pTmp -> uDataSize = uSize; - pTmp -> pPrev = NULL; + /* Fill up the structure */ + *((uint32*) ((char*) &pTmp->lSpecialValue+sf_malloc_prehunc))= MAGICKEY; + pTmp->aData[uSize + sf_malloc_prehunc+0]= MAGICEND0; + pTmp->aData[uSize + sf_malloc_prehunc+1]= MAGICEND1; + pTmp->aData[uSize + sf_malloc_prehunc+2]= MAGICEND2; + pTmp->aData[uSize + sf_malloc_prehunc+3]= MAGICEND3; + pTmp->sFileName= (my_string) sFile; + pTmp->uLineNum= uLine; + pTmp->uDataSize= uSize; + pTmp->pPrev= NULL; - /* Add this remember structure to the linked list */ - pthread_mutex_lock(&THR_LOCK_malloc); - if ((pTmp->pNext=pRememberRoot)) - { - pRememberRoot -> pPrev = pTmp; - } - pRememberRoot = pTmp; + /* Add this remember structure to the linked list */ + pthread_mutex_lock(&THR_LOCK_malloc); + if ((pTmp->pNext= pRememberRoot)) + pRememberRoot->pPrev= pTmp; + pRememberRoot= pTmp; - /* Keep the statistics */ - lCurMemory += uSize; - if (lCurMemory > lMaxMemory) { - lMaxMemory = lCurMemory; - } - cNewCount++; - pthread_mutex_unlock(&THR_LOCK_malloc); + /* Keep the statistics */ + lCurMemory+= uSize; + if (lCurMemory > lMaxMemory) + lMaxMemory= lCurMemory; + cNewCount++; + pthread_mutex_unlock(&THR_LOCK_malloc); - /* Set the memory to the aribtrary wierd value */ - if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick) - bfill(&pTmp -> aData[sf_malloc_prehunc],uSize, - (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL)); - /* Return a pointer to the real data */ - DBUG_PRINT("exit",("ptr: %lx",&(pTmp -> aData[sf_malloc_prehunc]))); - if (sf_min_adress > &(pTmp -> aData[sf_malloc_prehunc])) - sf_min_adress = &(pTmp -> aData[sf_malloc_prehunc]); - if (sf_max_adress < &(pTmp -> aData[sf_malloc_prehunc])) - sf_max_adress = &(pTmp -> aData[sf_malloc_prehunc]); - DBUG_RETURN ((gptr) &(pTmp -> aData[sf_malloc_prehunc])); + /* Set the memory to the aribtrary wierd value */ + if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick) + bfill(&pTmp->aData[sf_malloc_prehunc],uSize, + (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL)); + /* Return a pointer to the real data */ + DBUG_PRINT("exit",("ptr: %lx",&(pTmp->aData[sf_malloc_prehunc]))); + if (sf_min_adress > &(pTmp->aData[sf_malloc_prehunc])) + sf_min_adress= &(pTmp->aData[sf_malloc_prehunc]); + if (sf_max_adress < &(pTmp->aData[sf_malloc_prehunc])) + sf_max_adress= &(pTmp->aData[sf_malloc_prehunc]); + DBUG_RETURN ((gptr) &(pTmp->aData[sf_malloc_prehunc])); } /* @@ -218,8 +213,8 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags) Free then old memoryblock */ -gptr _myrealloc (register gptr pPtr, register uint uSize, - const char *sFile, uint uLine, myf MyFlags) +gptr _myrealloc(register gptr pPtr, register uint uSize, + const char *sFile, uint uLine, myf MyFlags) { struct remember *pRec; gptr ptr; @@ -234,9 +229,9 @@ gptr _myrealloc (register gptr pPtr, register uint uSize, if (check_ptr("Reallocating",(byte*) pPtr,sFile,uLine)) DBUG_RETURN((gptr) NULL); - pRec = (struct remember *) ((char*) pPtr - ALIGN_SIZE(sizeof(struct irem))- + pRec= (struct remember *) ((char*) pPtr - ALIGN_SIZE(sizeof(struct irem))- sf_malloc_prehunc); - if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) + if (*((uint32*) ((char*) &pRec->lSpecialValue+sf_malloc_prehunc)) != MAGICKEY) { fprintf(stderr, "Error: Reallocating unallocated data at line %d, '%s'\n", @@ -266,7 +261,7 @@ gptr _myrealloc (register gptr pPtr, register uint uSize, /* Deallocate some memory. */ -void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags) +void _myfree(gptr pPtr, const char *sFile, uint uLine, myf myflags) { struct remember *pRec; DBUG_ENTER("_myfree"); @@ -280,19 +275,19 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags) DBUG_VOID_RETURN; /* Calculate the address of the remember structure */ - pRec = (struct remember *) ((byte*) pPtr- ALIGN_SIZE(sizeof(struct irem))- + pRec= (struct remember *) ((byte*) pPtr- ALIGN_SIZE(sizeof(struct irem))- sf_malloc_prehunc); /* Check to make sure that we have a real remember structure. Note: this test could fail for four reasons: - (1) The memory was already free'ed - (2) The memory was never new'ed - (3) There was an underrun - (4) A stray pointer hit this location + (1) The memory was already free'ed + (2) The memory was never new'ed + (3) There was an underrun + (4) A stray pointer hit this location */ - if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) + if (*((uint32*) ((char*) &pRec->lSpecialValue+sf_malloc_prehunc)) != MAGICKEY) { fprintf(stderr, "Error: Freeing unallocated data at line %d, '%s'\n", @@ -304,16 +299,15 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags) /* Remove this structure from the linked list */ pthread_mutex_lock(&THR_LOCK_malloc); - if (pRec -> pPrev) { - pRec -> pPrev -> pNext = pRec -> pNext; - } else { - pRememberRoot = pRec -> pNext; - } - if (pRec -> pNext) { - pRec -> pNext -> pPrev = pRec -> pPrev; - } + if (pRec->pPrev) + pRec->pPrev->pNext= pRec->pNext; + else + pRememberRoot= pRec->pNext; + + if (pRec->pNext) + pRec->pNext->pPrev= pRec->pPrev; /* Handle the statistics */ - lCurMemory -= pRec -> uDataSize; + lCurMemory -= pRec->uDataSize; cNewCount--; pthread_mutex_unlock(&THR_LOCK_malloc); @@ -322,7 +316,7 @@ void _myfree (gptr pPtr, const char *sFile, uint uLine, myf myflags) if (!sf_malloc_quick) bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL); #endif - *((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) = ~MAGICKEY; + *((uint32*) ((char*) &pRec->lSpecialValue+sf_malloc_prehunc))= ~MAGICKEY; /* Actually free the memory */ free ((my_string ) pRec); @@ -372,7 +366,7 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile, free'ed as well as the statistics. */ -void TERMINATE (FILE *file) +void TERMINATE(FILE *file) { struct remember *pPtr; DBUG_ENTER("TERMINATE"); @@ -403,7 +397,8 @@ void TERMINATE (FILE *file) { if (file) { - fprintf(file, "Warning: Memory that was not free'ed (%ld bytes):\n",lCurMemory); + fprintf(file, "Warning: Memory that was not free'ed (%ld bytes):\n", + lCurMemory); (void) fflush(file); } DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",lCurMemory)); @@ -413,17 +408,17 @@ void TERMINATE (FILE *file) { fprintf(file, "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'", - pPtr -> uDataSize, - (ulong) &(pPtr -> aData[sf_malloc_prehunc]), - pPtr -> uLineNum, pPtr -> sFileName); + pPtr->uDataSize, + (ulong) &(pPtr->aData[sf_malloc_prehunc]), + pPtr->uLineNum, pPtr->sFileName); fprintf(file, "\n"); (void) fflush(file); } DBUG_PRINT("safe", ("%6u bytes at 0x%09lx, allocated at line %4d in '%s'", - pPtr -> uDataSize, &(pPtr -> aData[sf_malloc_prehunc]), - pPtr -> uLineNum, pPtr -> sFileName)); - pPtr = pPtr -> pNext; + pPtr->uDataSize, &(pPtr->aData[sf_malloc_prehunc]), + pPtr->uLineNum, pPtr->sFileName)); + pPtr= pPtr->pNext; } } /* Report the memory usage statistics */ @@ -442,44 +437,44 @@ void TERMINATE (FILE *file) /* Returns 0 if chunk is ok */ -static int _checkchunk (register struct remember *pRec, const char *sFile, - uint uLine) +static int _checkchunk(register struct remember *pRec, const char *sFile, + uint uLine) { reg1 uint uSize; reg2 my_string magicp; reg3 int flag=0; /* Check for a possible underrun */ - if (*((long*) ((char*) &pRec -> lSpecialValue+sf_malloc_prehunc)) + if (*((uint32*) ((char*) &pRec->lSpecialValue+sf_malloc_prehunc)) != MAGICKEY) { fprintf(stderr, "Error: Memory allocated at %s:%d was underrun,", - pRec -> sFileName, pRec -> uLineNum); + pRec->sFileName, pRec->uLineNum); fprintf(stderr, " discovered at %s:%d\n", sFile, uLine); (void) fflush(stderr); DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d", - &(pRec -> aData[sf_malloc_prehunc]), - pRec -> sFileName, - pRec -> uLineNum)); + &(pRec->aData[sf_malloc_prehunc]), + pRec->sFileName, + pRec->uLineNum)); flag=1; } /* Check for a possible overrun */ - uSize = pRec -> uDataSize; - magicp = &(pRec -> aData[uSize+sf_malloc_prehunc]); + uSize= pRec->uDataSize; + magicp= &(pRec->aData[uSize+sf_malloc_prehunc]); if (*magicp++ != MAGICEND0 || *magicp++ != MAGICEND1 || *magicp++ != MAGICEND2 || *magicp++ != MAGICEND3) { fprintf(stderr, "Error: Memory allocated at %s:%d was overrun,", - pRec -> sFileName, pRec -> uLineNum); + pRec->sFileName, pRec->uLineNum); fprintf(stderr, " discovered at '%s:%d'\n", sFile, uLine); (void) fflush(stderr); DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d", - &(pRec -> aData[sf_malloc_prehunc]), - pRec -> sFileName, - pRec -> uLineNum)); + &(pRec->aData[sf_malloc_prehunc]), + pRec->sFileName, + pRec->uLineNum)); flag=1; } return(flag); @@ -488,7 +483,7 @@ static int _checkchunk (register struct remember *pRec, const char *sFile, /* Returns how many wrong chunks */ -int _sanity (const char *sFile, uint uLine) +int _sanity(const char *sFile, uint uLine) { reg1 struct remember *pTmp; reg2 int flag=0; @@ -500,8 +495,8 @@ int _sanity (const char *sFile, uint uLine) cNewCount=0; #endif count=cNewCount; - for (pTmp = pRememberRoot; pTmp != NULL && count-- ; pTmp = pTmp -> pNext) - flag+=_checkchunk (pTmp, sFile, uLine); + for (pTmp= pRememberRoot; pTmp != NULL && count-- ; pTmp= pTmp->pNext) + flag+= _checkchunk (pTmp, sFile, uLine); pthread_mutex_unlock(&THR_LOCK_malloc); if (count || pTmp) { From 4302bfdb7de91da30ef4a2a7bcaa09954062d606 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Thu, 12 Jun 2003 17:05:45 +0200 Subject: [PATCH 020/237] typed moved to a proper place --- include/my_global.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 1026e8e3940..e5cb75365b4 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -640,9 +640,6 @@ typedef long my_ptrdiff_t; typedef long long my_ptrdiff_t; #endif -/* typedef used for length of string; Should be unsigned! */ -typedef ulong size_str; - #define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1)) #define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double)) /* Size to make adressable obj. */ @@ -711,6 +708,9 @@ typedef long longlong; #endif #endif +/* typedef used for length of string; Should be unsigned! */ +typedef ulong size_str; + #ifdef USE_RAID /* The following is done with a if to not get problems with pre-processors From 36aae14f1aca76ff8dc84f7ae5c7db93ba6536cc Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Thu, 12 Jun 2003 17:38:15 +0200 Subject: [PATCH 021/237] HANDLER priv check fixed --- sql/sql_parse.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7447ba44e76..9524c832856 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2476,8 +2476,10 @@ mysql_execute_command(void) res = mysql_ha_close(thd, tables); break; case SQLCOM_HA_READ: - if (check_db_used(thd,tables) || - check_table_access(thd,SELECT_ACL, tables)) + /* there is no need to check for table permissions here, because + if a user has no permissions to read a table, he won't be + able to open it (with SQLCOM_HA_OPEN) in the first place. */ + if (check_db_used(thd,tables)) goto error; res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir, lex->insert_list, lex->ha_rkey_mode, select_lex->where, From 977c66b4e7262d2ddfb721d9cd828c5824b6a024 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Thu, 12 Jun 2003 18:46:12 +0200 Subject: [PATCH 022/237] removed a wrong cast that limited ulonglong options to max. ulong value. --- mysys/my_getopt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 759c96462f6..e18c5a0b9eb 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -609,9 +609,9 @@ static ulonglong getopt_ull(char *arg, const struct my_option *optp, int *err) ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp) { - if ((ulonglong) num > (ulonglong) (ulong) optp->max_value && + if ((ulonglong) num > (ulonglong) optp->max_value && optp->max_value) /* if max value is not set -> no upper limit */ - num= (ulonglong) (ulong) optp->max_value; + num= (ulonglong) optp->max_value; if (optp->block_size > 1) { num/= (ulonglong) optp->block_size; From ecdb1c768ca856c8eef5389f02a2879c17688b21 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Thu, 12 Jun 2003 22:39:45 +0300 Subject: [PATCH 023/237] Changed safemalloc structure to not have to be 8 byte aligned. (Portability problem) --- include/my_sys.h | 4 +- mysys/default.c | 2 - mysys/my_static.c | 11 +- mysys/my_static.h | 32 +++-- mysys/safemalloc.c | 305 ++++++++++++++++++++++----------------------- sql/mysqld.cc | 2 +- sql/sql_parse.cc | 5 +- 7 files changed, 173 insertions(+), 188 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 603b3bad6bd..7f8b8a80a1c 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -138,7 +138,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define QUICK_SAFEMALLOC sf_malloc_quick=1 #define NORMAL_SAFEMALLOC sf_malloc_quick=0 extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick; -extern ulonglong safemalloc_mem_limit; +extern ulonglong sf_malloc_mem_limit; #define CALLER_INFO_PROTO , const char *sFile, uint uLine #define CALLER_INFO , __FILE__, __LINE__ @@ -239,7 +239,7 @@ extern int NEAR my_umask, /* Default creation mask */ NEAR my_safe_to_handle_signal, /* Set when allowed to SIGTSTP */ NEAR my_dont_interrupt; /* call remember_intr when set */ extern my_bool NEAR mysys_uses_curses, my_use_symdir; -extern long lCurMemory,lMaxMemory; /* from safemalloc */ +extern ulong sf_malloc_cur_memory, sf_malloc_max_memory; extern ulong my_default_record_cache_size; extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io, diff --git a/mysys/default.c b/mysys/default.c index 3ff240da3a1..cdacc8bee2b 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -33,8 +33,6 @@ ** --print-defaults ; Print the modified command line and exit ****************************************************************************/ -#undef SAFEMALLOC /* safe_malloc is not yet initailized */ - #include "mysys_priv.h" #include "m_string.h" #include "m_ctype.h" diff --git a/mysys/my_static.c b/mysys/my_static.c index bbf7582a454..b24ef28b7b1 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -69,14 +69,13 @@ uint sf_malloc_prehunc=0, /* If you have problem with core- */ sf_malloc_endhunc=0, /* dump when malloc-message.... */ /* set theese to 64 or 128 */ sf_malloc_quick=0; /* set if no calls to sanity */ -long lCurMemory = 0L; /* Current memory usage */ -long lMaxMemory = 0L; /* Maximum memory usage */ -uint cNewCount = 0; /* Number of times NEW() was called */ +ulong sf_malloc_cur_memory= 0L; /* Current memory usage */ +ulong sf_malloc_max_memory= 0L; /* Maximum memory usage */ +uint sf_malloc_count= 0; /* Number of times NEW() was called */ byte *sf_min_adress= (byte*) ~(unsigned long) 0L, *sf_max_adress= (byte*) 0L; - -/* Root of the linked list of remembers */ -struct remember *pRememberRoot = NULL; +/* Root of the linked list of struct st_irem */ +struct st_irem *sf_malloc_root = NULL; /* from my_alarm */ int volatile my_have_got_alarm=0; /* declare variable to reset */ diff --git a/mysys/my_static.h b/mysys/my_static.h index c1893f4074f..1a33bcf21f3 100644 --- a/mysys/my_static.h +++ b/mysys/my_static.h @@ -33,27 +33,23 @@ struct st_remember { }; /* - The size of the following structure MUST be dividable by 8 to not cause - alignment problems on some cpu's + Structure that stores information of a allocated memory block + The data is at &struct_adr+sizeof(ALIGN_SIZE(sizeof(struct irem))) + The lspecialvalue is at the previous 4 bytes from this, which may not + necessarily be in the struct if the struct size isn't aligned at a 8 byte + boundary. */ -struct irem +struct st_irem { - struct remember *_pNext; /* Linked list of structures */ - struct remember *_pPrev; /* Other link */ - char *_sFileName; /* File in which memory was new'ed */ - uint32 _uLineNum; /* Line number in above file */ - uint32 _uDataSize; /* Size requested */ -#if SIZEOF_CHARP == 8 - long _filler; /* For alignment */ -#endif - long _lSpecialValue; /* Underrun marker value */ + struct st_irem *next; /* Linked list of structures */ + struct st_irem *prev; /* Other link */ + char *filename; /* File in which memory was new'ed */ + uint32 linenum; /* Line number in above file */ + uint32 datasize; /* Size requested */ + uint32 SpecialValue; /* Underrun marker value */ }; -struct remember { - struct irem tInt; - char aData[1]; -}; extern char NEAR curr_dir[FN_REFLEN],NEAR home_dir_buff[FN_REFLEN]; @@ -70,8 +66,8 @@ extern int _my_tempnam_used; #endif extern byte *sf_min_adress,*sf_max_adress; -extern uint cNewCount; -extern struct remember *pRememberRoot; +extern uint sf_malloc_count; +extern struct st_irem *sf_malloc_root; #if defined(THREAD) && !defined(__WIN__) extern sigset_t my_signals; /* signals blocked by mf_brkhant */ diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 42cff1e5069..bd77b4821ff 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -69,18 +69,11 @@ #include "my_static.h" #include "mysys_err.h" -ulonglong safemalloc_mem_limit= ~(ulonglong)0; - -#define pNext tInt._pNext -#define pPrev tInt._pPrev -#define sFileName tInt._sFileName -#define uLineNum tInt._uLineNum -#define uDataSize tInt._uDataSize -#define lSpecialValue tInt._lSpecialValue +ulonglong sf_malloc_mem_limit= ~(ulonglong)0; #ifndef PEDANTIC_SAFEMALLOC /* - Set to 1 after TERMINATE() if we had to fiddle with cNewCount and + Set to 1 after TERMINATE() if we had to fiddle with sf_malloc_count and the linked list of blocks so that _sanity() will not fuss when it is not supposed to */ @@ -92,7 +85,7 @@ static int sf_malloc_tampered= 0; static int check_ptr(const char *where, byte *ptr, const char *sFile, uint uLine); -static int _checkchunk(struct irem *pRec, const char *sFile, uint uLine); +static int _checkchunk(struct st_irem *pRec, const char *sFile, uint uLine); /* Note: We only fill up the allocated block. This do not include @@ -127,29 +120,29 @@ static int _checkchunk(struct irem *pRec, const char *sFile, uint uLine); /* Allocate some memory. */ -gptr _mymalloc(uint uSize, const char *sFile, uint uLine, myf MyFlags) +gptr _mymalloc(uint size, const char *filename, uint lineno, myf MyFlags) { - struct remember *pTmp; + struct st_irem *irem; + char *data; DBUG_ENTER("_mymalloc"); - DBUG_PRINT("enter",("Size: %u",uSize)); + DBUG_PRINT("enter",("Size: %u",size)); if (!sf_malloc_quick) - (void) _sanity (sFile, uLine); + (void) _sanity (filename, lineno); - if (uSize + lCurMemory > safemalloc_mem_limit) - pTmp= 0; + if (size + sf_malloc_cur_memory > sf_malloc_mem_limit) + irem= 0; else { /* Allocate the physical memory */ - pTmp= (struct remember *) malloc (ALIGN_SIZE(sizeof(struct irem)) + - sf_malloc_prehunc + - uSize + /* size requested */ - 4 + /* overrun mark */ - sf_malloc_endhunc - ); + irem= (struct st_irem *) malloc (ALIGN_SIZE(sizeof(struct st_irem)) + + sf_malloc_prehunc + + size + /* size requested */ + 4 + /* overrun mark */ + sf_malloc_endhunc); } /* Check if there isn't anymore memory avaiable */ - if (pTmp == NULL) + if (!irem) { if (MyFlags & MY_FAE) error_handler_hook=fatal_error_handler_hook; @@ -157,126 +150,127 @@ gptr _mymalloc(uint uSize, const char *sFile, uint uLine, myf MyFlags) { char buff[SC_MAXWIDTH]; my_errno=errno; - sprintf(buff,"Out of memory at line %d, '%s'", uLine, sFile); + sprintf(buff,"Out of memory at line %d, '%s'", lineno, filename); my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)", - uSize, (uSize + 1023L) / 1024L, - lMaxMemory, (lMaxMemory + 1023L) / 1024L); + size, (size + 1023L) / 1024L, + sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L); my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); } DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'", - lMaxMemory,uLine, sFile)); + sf_malloc_max_memory,lineno, filename)); if (MyFlags & MY_FAE) exit(1); - DBUG_RETURN ((gptr) NULL); + DBUG_RETURN ((gptr) 0); } /* Fill up the structure */ - *((uint32*) ((char*) &pTmp->lSpecialValue+sf_malloc_prehunc))= MAGICKEY; - pTmp->aData[uSize + sf_malloc_prehunc+0]= MAGICEND0; - pTmp->aData[uSize + sf_malloc_prehunc+1]= MAGICEND1; - pTmp->aData[uSize + sf_malloc_prehunc+2]= MAGICEND2; - pTmp->aData[uSize + sf_malloc_prehunc+3]= MAGICEND3; - pTmp->sFileName= (my_string) sFile; - pTmp->uLineNum= uLine; - pTmp->uDataSize= uSize; - pTmp->pPrev= NULL; + data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) + + sf_malloc_prehunc); + *((uint32*) (data-sizeof(uint32)))= MAGICKEY; + data[size + 0]= MAGICEND0; + data[size + 1]= MAGICEND1; + data[size + 2]= MAGICEND2; + data[size + 3]= MAGICEND3; + irem->filename= (my_string) filename; + irem->linenum= lineno; + irem->datasize= size; + irem->prev= NULL; /* Add this remember structure to the linked list */ pthread_mutex_lock(&THR_LOCK_malloc); - if ((pTmp->pNext= pRememberRoot)) - pRememberRoot->pPrev= pTmp; - pRememberRoot= pTmp; + if ((irem->next= sf_malloc_root)) + sf_malloc_root->prev= irem; + sf_malloc_root= irem; /* Keep the statistics */ - lCurMemory+= uSize; - if (lCurMemory > lMaxMemory) - lMaxMemory= lCurMemory; - cNewCount++; + sf_malloc_cur_memory+= size; + if (sf_malloc_cur_memory > sf_malloc_max_memory) + sf_malloc_max_memory= sf_malloc_cur_memory; + sf_malloc_count++; pthread_mutex_unlock(&THR_LOCK_malloc); /* Set the memory to the aribtrary wierd value */ if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick) - bfill(&pTmp->aData[sf_malloc_prehunc],uSize, - (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL)); + bfill(data, size, (char) (MyFlags & MY_ZEROFILL ? 0 : ALLOC_VAL)); /* Return a pointer to the real data */ - DBUG_PRINT("exit",("ptr: %lx",&(pTmp->aData[sf_malloc_prehunc]))); - if (sf_min_adress > &(pTmp->aData[sf_malloc_prehunc])) - sf_min_adress= &(pTmp->aData[sf_malloc_prehunc]); - if (sf_max_adress < &(pTmp->aData[sf_malloc_prehunc])) - sf_max_adress= &(pTmp->aData[sf_malloc_prehunc]); - DBUG_RETURN ((gptr) &(pTmp->aData[sf_malloc_prehunc])); + DBUG_PRINT("exit",("ptr: %lx", data)); + if (sf_min_adress > data) + sf_min_adress= data; + if (sf_max_adress < data) + sf_max_adress= data; + DBUG_RETURN ((gptr) data); } + /* Allocate some new memory and move old memoryblock there. Free then old memoryblock */ -gptr _myrealloc(register gptr pPtr, register uint uSize, - const char *sFile, uint uLine, myf MyFlags) +gptr _myrealloc(register gptr ptr, register uint size, + const char *filename, uint lineno, myf MyFlags) { - struct remember *pRec; - gptr ptr; + struct st_irem *irem; + char *data; DBUG_ENTER("_myrealloc"); - if (!pPtr && (MyFlags & MY_ALLOW_ZERO_PTR)) - DBUG_RETURN(_mymalloc(uSize,sFile,uLine,MyFlags)); + if (!ptr && (MyFlags & MY_ALLOW_ZERO_PTR)) + DBUG_RETURN(_mymalloc(size, filename, lineno, MyFlags)); if (!sf_malloc_quick) - (void) _sanity (sFile, uLine); + (void) _sanity (filename, lineno); - if (check_ptr("Reallocating",(byte*) pPtr,sFile,uLine)) + if (check_ptr("Reallocating", (byte*) ptr, filename, lineno)) DBUG_RETURN((gptr) NULL); - pRec= (struct remember *) ((char*) pPtr - ALIGN_SIZE(sizeof(struct irem))- - sf_malloc_prehunc); - if (*((uint32*) ((char*) &pRec->lSpecialValue+sf_malloc_prehunc)) - != MAGICKEY) + irem= (struct st_irem *) (((char*) ptr) - ALIGN_SIZE(sizeof(struct st_irem))- + sf_malloc_prehunc); + if (*((uint32*) (((char*) ptr)- sizeof(uint32))) != MAGICKEY) { fprintf(stderr, "Error: Reallocating unallocated data at line %d, '%s'\n", - uLine, sFile); + lineno, filename); DBUG_PRINT("safe",("Reallocating unallocated data at line %d, '%s'", - uLine, sFile)); + lineno, filename)); (void) fflush(stderr); DBUG_RETURN((gptr) NULL); } - if ((ptr=_mymalloc(uSize,sFile,uLine,MyFlags))) /* Allocate new area */ + if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */ { - uSize=min(uSize,pRec-> uDataSize); /* Move as much as possibly */ - memcpy((byte*) ptr,pPtr,(size_t) uSize); /* Copy old data */ - _myfree(pPtr,sFile,uLine,0); /* Free not needed area */ + size=min(size, irem->datasize); /* Move as much as possibly */ + memcpy((byte*) data, ptr, (size_t) size); /* Copy old data */ + _myfree(ptr, filename, lineno, 0); /* Free not needed area */ } else { if (MyFlags & MY_HOLD_ON_ERROR) - DBUG_RETURN(pPtr); + DBUG_RETURN(ptr); if (MyFlags & MY_FREE_ON_ERROR) - _myfree(pPtr,sFile,uLine,0); + _myfree(ptr, filename, lineno, 0); } - DBUG_RETURN(ptr); + DBUG_RETURN(data); } /* _myrealloc */ /* Deallocate some memory. */ -void _myfree(gptr pPtr, const char *sFile, uint uLine, myf myflags) +void _myfree(gptr ptr, const char *filename, uint lineno, myf myflags) { - struct remember *pRec; + struct st_irem *irem; DBUG_ENTER("_myfree"); - DBUG_PRINT("enter",("ptr: %lx",pPtr)); + DBUG_PRINT("enter",("ptr: %lx", ptr)); if (!sf_malloc_quick) - (void) _sanity (sFile, uLine); + (void) _sanity (filename, lineno); - if ((!pPtr && (myflags & MY_ALLOW_ZERO_PTR)) || - check_ptr("Freeing",(byte*) pPtr,sFile,uLine)) + if ((!ptr && (myflags & MY_ALLOW_ZERO_PTR)) || + check_ptr("Freeing",(byte*) ptr,filename,lineno)) DBUG_VOID_RETURN; /* Calculate the address of the remember structure */ - pRec= (struct remember *) ((byte*) pPtr- ALIGN_SIZE(sizeof(struct irem))- - sf_malloc_prehunc); + irem= (struct st_irem *) ((char*) ptr- ALIGN_SIZE(sizeof(struct st_irem))- + sf_malloc_prehunc); /* Check to make sure that we have a real remember structure. @@ -287,52 +281,50 @@ void _myfree(gptr pPtr, const char *sFile, uint uLine, myf myflags) (4) A stray pointer hit this location */ - if (*((uint32*) ((char*) &pRec->lSpecialValue+sf_malloc_prehunc)) - != MAGICKEY) + if (*((uint32*) ((char*) ptr- sizeof(uint32))) != MAGICKEY) { fprintf(stderr, "Error: Freeing unallocated data at line %d, '%s'\n", - uLine, sFile); - DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",uLine,sFile)); + lineno, filename); + DBUG_PRINT("safe",("Unallocated data at line %d, '%s'",lineno,filename)); (void) fflush(stderr); DBUG_VOID_RETURN; } /* Remove this structure from the linked list */ pthread_mutex_lock(&THR_LOCK_malloc); - if (pRec->pPrev) - pRec->pPrev->pNext= pRec->pNext; + if (irem->prev) + irem->prev->next= irem->next; else - pRememberRoot= pRec->pNext; + sf_malloc_root= irem->next; - if (pRec->pNext) - pRec->pNext->pPrev= pRec->pPrev; + if (irem->next) + irem->next->prev= irem->prev; /* Handle the statistics */ - lCurMemory -= pRec->uDataSize; - cNewCount--; + sf_malloc_cur_memory-= irem->datasize; + sf_malloc_count--; pthread_mutex_unlock(&THR_LOCK_malloc); #ifndef HAVE_purify /* Mark this data as free'ed */ if (!sf_malloc_quick) - bfill(&pRec->aData[sf_malloc_prehunc],pRec->uDataSize,(pchar) FREE_VAL); + bfill(ptr, irem->datasize, (pchar) FREE_VAL); #endif - *((uint32*) ((char*) &pRec->lSpecialValue+sf_malloc_prehunc))= ~MAGICKEY; - + *((uint32*) ((char*) ptr- sizeof(uint32)))= ~MAGICKEY; /* Actually free the memory */ - free ((my_string ) pRec); + free((char*) irem); DBUG_VOID_RETURN; } /* Check if we have a wrong pointer */ -static int check_ptr(const char *where, byte *ptr, const char *sFile, - uint uLine) +static int check_ptr(const char *where, byte *ptr, const char *filename, + uint lineno) { if (!ptr) { fprintf(stderr, "Error: %s NULL pointer at line %d, '%s'\n", - where,uLine, sFile); - DBUG_PRINT("safe",("Null pointer at line %d '%s'", uLine, sFile)); + where,lineno, filename); + DBUG_PRINT("safe",("Null pointer at line %d '%s'", lineno, filename)); (void) fflush(stderr); return 1; } @@ -340,9 +332,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile, if ((long) ptr & (ALIGN_SIZE(1)-1)) { fprintf(stderr, "Error: %s wrong aligned pointer at line %d, '%s'\n", - where,uLine, sFile); + where,lineno, filename); DBUG_PRINT("safe",("Wrong aligned pointer at line %d, '%s'", - uLine,sFile)); + lineno,filename)); (void) fflush(stderr); return 1; } @@ -350,9 +342,9 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile, if (ptr < sf_min_adress || ptr > sf_max_adress) { fprintf(stderr, "Error: %s pointer out of range at line %d, '%s'\n", - where,uLine, sFile); + where,lineno, filename); DBUG_PRINT("safe",("Pointer out of range at line %d '%s'", - uLine,sFile)); + lineno,filename)); (void) fflush(stderr); return 1; } @@ -368,7 +360,7 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile, void TERMINATE(FILE *file) { - struct remember *pPtr; + struct st_irem *irem; DBUG_ENTER("TERMINATE"); pthread_mutex_lock(&THR_LOCK_malloc); @@ -378,14 +370,15 @@ void TERMINATE(FILE *file) NEWs than FREEs. <0, etc. */ - if (cNewCount) + if (sf_malloc_count) { if (file) { - fprintf(file, "Warning: Not freed memory segments: %d\n", cNewCount); + fprintf(file, "Warning: Not freed memory segments: %d\n", + sf_malloc_count); (void) fflush(file); } - DBUG_PRINT("safe",("cNewCount: %d",cNewCount)); + DBUG_PRINT("safe",("sf_malloc_count: %d", sf_malloc_count)); } /* @@ -393,43 +386,44 @@ void TERMINATE(FILE *file) but not free'ed with FREE. */ - if ((pPtr=pRememberRoot)) + if ((irem= sf_malloc_root)) { if (file) { fprintf(file, "Warning: Memory that was not free'ed (%ld bytes):\n", - lCurMemory); + sf_malloc_cur_memory); (void) fflush(file); } - DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):",lCurMemory)); - while (pPtr) + DBUG_PRINT("safe",("Memory that was not free'ed (%ld bytes):", + sf_malloc_cur_memory)); + while (irem) { + char *data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) + + sf_malloc_prehunc); if (file) { fprintf(file, "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'", - pPtr->uDataSize, - (ulong) &(pPtr->aData[sf_malloc_prehunc]), - pPtr->uLineNum, pPtr->sFileName); + irem->datasize, (long) data, irem->linenum, irem->filename); fprintf(file, "\n"); (void) fflush(file); } DBUG_PRINT("safe", ("%6u bytes at 0x%09lx, allocated at line %4d in '%s'", - pPtr->uDataSize, &(pPtr->aData[sf_malloc_prehunc]), - pPtr->uLineNum, pPtr->sFileName)); - pPtr= pPtr->pNext; + irem->datasize, data, irem->linenum, irem->filename)); + irem= irem->next; } } /* Report the memory usage statistics */ if (file) { fprintf(file, "Maximum memory usage: %ld bytes (%ldk)\n", - lMaxMemory, (lMaxMemory + 1023L) / 1024L); + sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L); (void) fflush(file); } DBUG_PRINT("safe",("Maximum memory usage: %ld bytes (%ldk)", - lMaxMemory, (lMaxMemory + 1023L) / 1024L)); + sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / + 1024L)); pthread_mutex_unlock(&THR_LOCK_malloc); DBUG_VOID_RETURN; } @@ -437,44 +431,41 @@ void TERMINATE(FILE *file) /* Returns 0 if chunk is ok */ -static int _checkchunk(register struct remember *pRec, const char *sFile, - uint uLine) +static int _checkchunk(register struct st_irem *irem, const char *filename, + uint lineno) { - reg1 uint uSize; - reg2 my_string magicp; - reg3 int flag=0; + int flag=0; + char *magicp, *data; + data= (((char*) irem) + ALIGN_SIZE(sizeof(struct st_irem)) + + sf_malloc_prehunc); /* Check for a possible underrun */ - if (*((uint32*) ((char*) &pRec->lSpecialValue+sf_malloc_prehunc)) - != MAGICKEY) + if (*((uint32*) (data- sizeof(uint32))) != MAGICKEY) { fprintf(stderr, "Error: Memory allocated at %s:%d was underrun,", - pRec->sFileName, pRec->uLineNum); - fprintf(stderr, " discovered at %s:%d\n", sFile, uLine); + irem->filename, irem->linenum); + fprintf(stderr, " discovered at %s:%d\n", filename, lineno); (void) fflush(stderr); DBUG_PRINT("safe",("Underrun at %lx, allocated at %s:%d", - &(pRec->aData[sf_malloc_prehunc]), - pRec->sFileName, - pRec->uLineNum)); + data, irem->filename, irem->linenum)); flag=1; } /* Check for a possible overrun */ - uSize= pRec->uDataSize; - magicp= &(pRec->aData[uSize+sf_malloc_prehunc]); + magicp= data + irem->datasize; if (*magicp++ != MAGICEND0 || *magicp++ != MAGICEND1 || *magicp++ != MAGICEND2 || *magicp++ != MAGICEND3) { fprintf(stderr, "Error: Memory allocated at %s:%d was overrun,", - pRec->sFileName, pRec->uLineNum); - fprintf(stderr, " discovered at '%s:%d'\n", sFile, uLine); + irem->filename, irem->linenum); + fprintf(stderr, " discovered at '%s:%d'\n", filename, lineno); (void) fflush(stderr); DBUG_PRINT("safe",("Overrun at %lx, allocated at %s:%d", - &(pRec->aData[sf_malloc_prehunc]), - pRec->sFileName, - pRec->uLineNum)); + data, + irem->filename, + irem->linenum)); flag=1; } return(flag); @@ -483,28 +474,28 @@ static int _checkchunk(register struct remember *pRec, const char *sFile, /* Returns how many wrong chunks */ -int _sanity(const char *sFile, uint uLine) +int _sanity(const char *filename, uint lineno) { - reg1 struct remember *pTmp; + reg1 struct st_irem *irem; reg2 int flag=0; uint count=0; pthread_mutex_lock(&THR_LOCK_malloc); #ifndef PEDANTIC_SAFEMALLOC - if (sf_malloc_tampered && cNewCount < 0) - cNewCount=0; + if (sf_malloc_tampered && sf_malloc_count < 0) + sf_malloc_count=0; #endif - count=cNewCount; - for (pTmp= pRememberRoot; pTmp != NULL && count-- ; pTmp= pTmp->pNext) - flag+= _checkchunk (pTmp, sFile, uLine); + count=sf_malloc_count; + for (irem= sf_malloc_root; irem != NULL && count-- ; irem= irem->next) + flag+= _checkchunk (irem, filename, lineno); pthread_mutex_unlock(&THR_LOCK_malloc); - if (count || pTmp) + if (count || irem) { const char *format="Error: Safemalloc link list destroyed, discovered at '%s:%d'"; - fprintf(stderr, format, sFile, uLine); fputc('\n',stderr); - fprintf(stderr, "root=%p,count=%d,pTmp=%p\n", pRememberRoot,count,pTmp); + fprintf(stderr, format, filename, lineno); fputc('\n',stderr); + fprintf(stderr, "root=%p,count=%d,irem=%p\n", sf_malloc_root,count,irem); (void) fflush(stderr); - DBUG_PRINT("safe",(format, sFile, uLine)); + DBUG_PRINT("safe",(format, filename, lineno)); flag=1; } return flag; @@ -513,33 +504,33 @@ int _sanity(const char *sFile, uint uLine) /* malloc and copy */ -gptr _my_memdup(const byte *from, uint length, const char *sFile, uint uLine, - myf MyFlags) +gptr _my_memdup(const byte *from, uint length, const char *filename, + uint lineno, myf MyFlags) { gptr ptr; - if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0) + if ((ptr=_mymalloc(length,filename,lineno,MyFlags)) != 0) memcpy((byte*) ptr, (byte*) from,(size_t) length); return(ptr); } /*_my_memdup */ -char *_my_strdup(const char *from, const char *sFile, uint uLine, +char *_my_strdup(const char *from, const char *filename, uint lineno, myf MyFlags) { gptr ptr; uint length=(uint) strlen(from)+1; - if ((ptr=_mymalloc(length,sFile,uLine,MyFlags)) != 0) + if ((ptr=_mymalloc(length,filename,lineno,MyFlags)) != 0) memcpy((byte*) ptr, (byte*) from,(size_t) length); return((char*) ptr); } /* _my_strdup */ char *_my_strdup_with_length(const byte *from, uint length, - const char *sFile, uint uLine, + const char *filename, uint lineno, myf MyFlags) { gptr ptr; - if ((ptr=_mymalloc(length+1,sFile,uLine,MyFlags)) != 0) + if ((ptr=_mymalloc(length+1,filename,lineno,MyFlags)) != 0) { memcpy((byte*) ptr, (byte*) from,(size_t) length); ptr[length]=0; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ca98ab96710..0f3500248c0 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4292,7 +4292,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case OPT_SAFEMALLOC_MEM_LIMIT: #if !defined(DBUG_OFF) && defined(SAFEMALLOC) - safemalloc_mem_limit = atoi(argument); + sf_malloc_mem_limit = atoi(argument); #endif break; #ifdef EMBEDDED_LIBRARY diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7447ba44e76..3e72bf1d919 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1208,9 +1208,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd, opened_tables,refresh_version, cached_tables(), uptime ? (float)thd->query_id/(float)uptime : 0); #ifdef SAFEMALLOC - if (lCurMemory) // Using SAFEMALLOC + if (sf_malloc_cur_memory) // Using SAFEMALLOC sprintf(strend(buff), " Memory in use: %ldK Max memory used: %ldK", - (lCurMemory+1023L)/1024L,(lMaxMemory+1023L)/1024L); + (sf_malloc_cur_memory+1023L)/1024L, + (sf_malloc_max_memory+1023L)/1024L); #endif VOID(my_net_write(net, buff,(uint) strlen(buff))); VOID(net_flush(net)); From 925f621c644a65f4283cd59c416207a686198172 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Fri, 13 Jun 2003 14:47:23 +0200 Subject: [PATCH 024/237] - replaced obsolete Macro AM_CONFIG_HEADER with AC_CONFIG_HEADERS - Added missing function name in checking for sem_init in posix4 libs on Solaris --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 9b6a174b0fb..d45aecdf494 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! AM_INIT_AUTOMAKE(mysql, 4.0.14) -AM_CONFIG_HEADER(config.h) +AC_CONFIG_HEADERS(config.h) PROTOCOL_VERSION=10 DOT_FRM_VERSION=6 @@ -757,7 +757,7 @@ AC_CHECK_LIB(crypt, crypt) AC_CHECK_FUNC(crypt, AC_DEFINE(HAVE_CRYPT)) # For sem_xxx functions on Solaris 2.6 -AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4)) +AC_CHECK_FUNC(sem_init, , AC_CHECK_LIB(posix4, sem_init)) # For compress in zlib MYSQL_CHECK_ZLIB_WITH_COMPRESS($with_named_zlib) From 8a52c2d20bdb23ef154aa5c6a5980a2d763c9c4e Mon Sep 17 00:00:00 2001 From: "jani@rhols221.adsl.netsonic.fi" <> Date: Sat, 14 Jun 2003 12:29:42 +0300 Subject: [PATCH 025/237] Added option --skip-kill-mysqld to mysqld_safe. This can be useful, if one is running many mysqlds through mysqld_multi, for example. Without this option, on Linux one mysqld_safe process may kill other mysqlds as well, if started using the same binary and path. --- scripts/mysqld_safe.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 626e04b1579..fcd8e26c901 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -10,6 +10,8 @@ # mysql.server works by first doing a cd to the base directory and from there # executing mysqld_safe +KILL_MYSQLD=1; + trap '' 1 2 3 15 # we shouldn't let anyone kill us umask 007 @@ -34,6 +36,9 @@ parse_arguments() { for arg do case "$arg" in + --skip-kill-mysqld*) + KILL_MYSQLD=0; + ;; # these get passed explicitly to mysqld --basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e "s;--basedir=;;"` ;; --datadir=*) DATADIR=`echo "$arg" | sed -e "s;--datadir=;;"` ;; @@ -83,6 +88,7 @@ parse_arguments() { done } + MY_PWD=`pwd` # Check if we are starting this relative (for the binary release) if test -d $MY_PWD/data/mysql -a -f ./share/mysql/english/errmsg.sys -a \ @@ -298,7 +304,7 @@ do break fi - if @IS_LINUX@ + if test @IS_LINUX@ -a $KILL_MYSQLD -eq 1 then # Test if one process was hanging. # This is only a fix for Linux (running as base 3 mysqld processes) From 28d3c3d76f7b573cb70838411a5a361907ae2953 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 14 Jun 2003 16:40:00 +0200 Subject: [PATCH 026/237] - Fix for bug 651: now a dying SQL slave threads wakes up any waiting MASTER_POS_WAIT(). Could not add a testcase for this: if the test goes into a MASTER_POS_WAIT, it waits until this terminates (even doing "connection other_con" to launch "stop slave" is blocked). - In MASTER_POS_WAIT() don't test if the I/O slave is running, but if the SQL thread is running. - Some DBUG info for this bugfix. --- sql/slave.cc | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index d2bc5b2f758..74005c65672 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -289,6 +289,9 @@ err: pthread_cond_broadcast(&rli->data_cond); if (need_data_lock) pthread_mutex_unlock(&rli->data_lock); + + /* Isn't this strange: if !need_data_lock, we broadcast with no lock ?? */ + pthread_mutex_unlock(log_lock); DBUG_RETURN ((*errmsg) ? 1 : 0); } @@ -1778,6 +1781,13 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, the master info. To catch this, these commands modify abort_pos_wait ; we just monitor abort_pos_wait and see if it has changed. + Why do we have this mechanism instead of simply monitoring slave_running in + the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that the + SQL thread be stopped? This is in case + STOP SLAVE;CHANGE MASTER/RESET SLAVE; START SLAVE; + happens very quickly between the moment pthread_cond_wait() wakes up and + the while() is evaluated: in that case slave_running is again 1 when the + while() is evaluated. */ init_abort_pos_wait= abort_pos_wait; @@ -1814,7 +1824,12 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, //"compare and wait" main loop while (!thd->killed && init_abort_pos_wait == abort_pos_wait && - mi->slave_running) + /* + formerly we tested mi->slave_running, but what we care about is + rli->slave_running (because this concerns the SQL thread, while + mi->slave_running concerns the I/O thread). + */ + slave_running) { bool pos_reached; int cmp_result= 0; @@ -1852,6 +1867,10 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, DBUG_PRINT("info",("Waiting for master update")); const char* msg = thd->enter_cond(&data_cond, &data_lock, "Waiting for master update"); + /* + We are going to pthread_cond_(timed)wait(); if the SQL thread stops it + will wake us up. + */ if (timeout > 0) { /* @@ -1869,6 +1888,7 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, } else pthread_cond_wait(&data_cond, &data_lock); + DBUG_PRINT("info",("Got signal of master update")); thd->exit_cond(msg); if (error == ETIMEDOUT || error == ETIME) { @@ -1877,6 +1897,7 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, } error=0; event_count++; + DBUG_PRINT("info",("Testing if killed or SQL thread not running")); } err: @@ -1885,11 +1906,11 @@ err: improper_arguments: %d timed_out: %d", (int) thd->killed, (int) (init_abort_pos_wait != abort_pos_wait), - (int) mi->slave_running, + (int) slave_running, (int) (error == -2), (int) (error == -1))); if (thd->killed || init_abort_pos_wait != abort_pos_wait || - !mi->slave_running) + !slave_running) { error= -2; } @@ -2596,8 +2617,15 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ VOID(pthread_mutex_unlock(&LOCK_thread_count)); thd->proc_info = "Waiting for slave mutex on exit"; pthread_mutex_lock(&rli->run_lock); + /* We need data_lock, at least to wake up any waiting master_pos_wait() */ + pthread_mutex_lock(&rli->data_lock); DBUG_ASSERT(rli->slave_running == 1); // tracking buffer overrun - rli->slave_running = 0; + /* When master_pos_wait() wakes up it will check this and terminate */ + rli->slave_running= 0; + /* Wake up master_pos_wait() */ + pthread_mutex_unlock(&rli->data_lock); + DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions")); + pthread_cond_broadcast(&rli->data_cond); rli->save_temporary_tables = thd->temporary_tables; /* From 4da7f485b75867dbc2ed02054459d1e8050144f3 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sun, 15 Jun 2003 01:04:28 +0300 Subject: [PATCH 027/237] Many files: Merge InnoDB-4.0.14: SAVEPOINT now implemented; InnoDB now accepts also column prefix keys; crashing bug in ON UPDATE CASCADE fixed; page checksum formula fixed --- include/my_base.h | 1 + innobase/btr/btr0cur.c | 66 ++--- innobase/btr/btr0pcur.c | 2 + innobase/buf/buf0buf.c | 112 ++++++--- innobase/buf/buf0flu.c | 26 +- innobase/data/data0data.c | 30 ++- innobase/data/data0type.c | 2 - innobase/dict/dict0boot.c | 16 +- innobase/dict/dict0crea.c | 28 ++- innobase/dict/dict0dict.c | 162 +++++++----- innobase/dict/dict0load.c | 28 ++- innobase/dict/dict0mem.c | 13 +- innobase/fil/fil0fil.c | 6 +- innobase/fsp/fsp0fsp.c | 4 +- innobase/ha/ha0ha.c | 8 +- innobase/ibuf/ibuf0ibuf.c | 8 +- innobase/include/btr0cur.h | 8 +- innobase/include/buf0buf.h | 17 +- innobase/include/data0data.h | 2 - innobase/include/data0type.h | 66 +++-- innobase/include/data0type.ic | 35 ++- innobase/include/db0err.h | 4 +- innobase/include/dict0dict.h | 13 + innobase/include/dict0mem.h | 25 +- innobase/include/fil0fil.h | 7 +- innobase/include/lock0lock.h | 12 + innobase/include/os0file.h | 23 ++ innobase/include/page0page.h | 9 + innobase/include/rem0cmp.h | 16 ++ innobase/include/row0mysql.ic | 4 +- innobase/include/row0row.h | 7 +- innobase/include/row0sel.h | 9 +- innobase/include/row0upd.h | 30 +-- innobase/include/srv0srv.h | 1 + innobase/include/trx0roll.h | 64 +++++ innobase/include/trx0sys.ic | 10 + innobase/include/trx0trx.h | 7 +- innobase/include/trx0types.h | 1 + innobase/include/ut0dbg.h | 31 +++ innobase/include/ut0mem.h | 2 +- innobase/lock/lock0lock.c | 86 ++++++- innobase/log/log0log.c | 45 +++- innobase/log/log0recv.c | 14 +- innobase/mem/mem0pool.c | 28 ++- innobase/os/os0file.c | 267 ++++++++++++++++++-- innobase/os/os0thread.c | 4 +- innobase/page/page0cur.c | 19 +- innobase/page/page0page.c | 54 +++- innobase/pars/pars0opt.c | 7 +- innobase/pars/pars0pars.c | 8 +- innobase/rem/rem0cmp.c | 117 ++++++--- innobase/row/row0ins.c | 134 ++++++++-- innobase/row/row0mysql.c | 60 ++--- innobase/row/row0row.c | 92 +++---- innobase/row/row0sel.c | 214 +++++++++++----- innobase/row/row0umod.c | 5 +- innobase/row/row0upd.c | 127 +++++----- innobase/row/row0vers.c | 12 +- innobase/srv/srv0srv.c | 16 +- innobase/srv/srv0start.c | 8 +- innobase/trx/trx0rec.c | 24 +- innobase/trx/trx0roll.c | 224 ++++++++++++++--- innobase/trx/trx0sys.c | 2 +- innobase/trx/trx0trx.c | 5 + innobase/ut/ut0mem.c | 14 +- innobase/ut/ut0ut.c | 2 + mysql-test/r/innodb.result | 10 - mysql-test/t/innodb.test | 9 - sql/ha_innodb.cc | 456 +++++++++++++++++++++++++++------- sql/ha_innodb.h | 19 +- sql/handler.cc | 65 ++++- sql/handler.h | 2 + sql/sql_lex.h | 5 +- sql/sql_parse.cc | 16 +- sql/sql_yacc.yy | 3 +- 75 files changed, 2300 insertions(+), 788 deletions(-) diff --git a/include/my_base.h b/include/my_base.h index cd04ab971db..91a248cd401 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -255,6 +255,7 @@ enum ha_base_keytype { #define HA_ERR_CANNOT_ADD_FOREIGN 150 /* Cannot add a foreign key constr. */ #define HA_ERR_NO_REFERENCED_ROW 151 /* Cannot add a child row */ #define HA_ERR_ROW_IS_REFERENCED 152 /* Cannot delete a parent row */ +#define HA_ERR_NO_SAVEPOINT 153 /* No savepoint with that name */ /* Other constants */ diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index e61dcf4ecee..8402993e971 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -1364,7 +1364,8 @@ btr_cur_update_sec_rec_in_place( } /***************************************************************** -Updates a record when the update causes no size changes in its fields. */ +Updates a record when the update causes no size changes in its fields. +We assume here that the ordering fields of the record do not change. */ ulint btr_cur_update_in_place( @@ -1455,7 +1456,8 @@ btr_cur_update_in_place( Tries to update a record on a page in an index tree. It is assumed that mtr holds an x-latch on the page. The operation does not succeed if there is too little space on the page or if the update would result in too empty a page, -so that tree compression is recommended. */ +so that tree compression is recommended. We assume here that the ordering +fields of the record do not change. */ ulint btr_cur_optimistic_update( @@ -1507,10 +1509,11 @@ btr_cur_optimistic_update( ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); - if (!row_upd_changes_field_size(rec, index, update)) { + if (!row_upd_changes_field_size_or_external(rec, index, update)) { - /* The simplest and most common case: the update does not - change the size of any field */ + /* The simplest and the most common case: the update does not + change the size of any field and none of the updated fields is + externally stored in rec or update */ return(btr_cur_update_in_place(flags, cursor, update, cmpl_info, thr, mtr)); @@ -1539,7 +1542,7 @@ btr_cur_optimistic_update( new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); - row_upd_clust_index_replace_new_col_vals(new_entry, update); + row_upd_index_replace_new_col_vals(new_entry, index, update, NULL); old_rec_size = rec_get_size(rec); new_rec_size = rec_get_converted_size(new_entry); @@ -1669,54 +1672,13 @@ btr_cur_pess_upd_restore_supremum( lock_rec_reset_and_inherit_gap_locks(page_get_supremum_rec(prev_page), rec); } - -/*************************************************************** -Replaces and copies the data in the new column values stored in the -update vector to the clustered index entry given. */ -static -void -btr_cur_copy_new_col_vals( -/*======================*/ - dtuple_t* entry, /* in/out: index entry where replaced */ - upd_t* update, /* in: update vector */ - mem_heap_t* heap) /* in: heap where data is copied */ -{ - upd_field_t* upd_field; - dfield_t* dfield; - dfield_t* new_val; - ulint field_no; - byte* data; - ulint i; - - dtuple_set_info_bits(entry, update->info_bits); - - for (i = 0; i < upd_get_n_fields(update); i++) { - - upd_field = upd_get_nth_field(update, i); - - field_no = upd_field->field_no; - - dfield = dtuple_get_nth_field(entry, field_no); - - new_val = &(upd_field->new_val); - - if (new_val->len == UNIV_SQL_NULL) { - data = NULL; - } else { - data = mem_heap_alloc(heap, new_val->len); - - ut_memcpy(data, new_val->data, new_val->len); - } - - dfield_set_data(dfield, data, new_val->len); - } -} /***************************************************************** Performs an update of a record on a page of a tree. It is assumed that mtr holds an x-latch on the tree and on the cursor page. If the update is made on the leaf level, to avoid deadlocks, mtr must also -own x-latches to brothers of page, if those brothers exist. */ +own x-latches to brothers of page, if those brothers exist. We assume +here that the ordering fields of the record do not change. */ ulint btr_cur_pessimistic_update( @@ -1813,7 +1775,7 @@ btr_cur_pessimistic_update( new_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); - btr_cur_copy_new_col_vals(new_entry, update, heap); + row_upd_index_replace_new_col_vals(new_entry, index, update, heap); if (!(flags & BTR_KEEP_SYS_FLAG)) { row_upd_index_entry_sys_field(new_entry, index, DATA_ROLL_PTR, @@ -3369,8 +3331,8 @@ btr_free_externally_stored_field( page_no = mach_read_from_4(data + local_len + BTR_EXTERN_PAGE_NO); - offset = mach_read_from_4(data + local_len + BTR_EXTERN_OFFSET); - + offset = mach_read_from_4(data + local_len + + BTR_EXTERN_OFFSET); extern_len = mach_read_from_4(data + local_len + BTR_EXTERN_LEN + 4); diff --git a/innobase/btr/btr0pcur.c b/innobase/btr/btr0pcur.c index 7b817d8263d..63e7763ef87 100644 --- a/innobase/btr/btr0pcur.c +++ b/innobase/btr/btr0pcur.c @@ -364,6 +364,8 @@ btr_pcur_move_to_next_page( btr_leaf_page_release(page, cursor->latch_mode, mtr); page_cur_set_before_first(next_page, btr_pcur_get_page_cur(cursor)); + + page_check_dir(next_page); } /************************************************************* diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index e000d862403..246a60a61cd 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -209,12 +209,12 @@ ibool buf_debug_prints = FALSE; /* If this is set TRUE, /************************************************************************ Calculates a page checksum which is stored to the page when it is written -to a file. Note that we must be careful to calculate the same value -on 32-bit and 64-bit architectures. */ +to a file. Note that we must be careful to calculate the same value on +32-bit and 64-bit architectures. */ ulint -buf_calc_page_checksum( -/*===================*/ +buf_calc_page_new_checksum( +/*=======================*/ /* out: checksum */ byte* page) /* in: buffer page */ { @@ -222,12 +222,39 @@ buf_calc_page_checksum( /* Since the fields FIL_PAGE_FILE_FLUSH_LSN and ..._ARCH_LOG_NO are written outside the buffer pool to the first pages of data - files, we have to skip them in page checksum calculation */ + files, we have to skip them in the page checksum calculation. + We must also skip the field FIL_PAGE_SPACE_OR_CHKSUM where the + checksum is stored, and also the last 8 bytes of page because + there we store the old formula checksum. */ + + checksum = ut_fold_binary(page + FIL_PAGE_OFFSET, + FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET) + + ut_fold_binary(page + FIL_PAGE_DATA, + UNIV_PAGE_SIZE - FIL_PAGE_DATA + - FIL_PAGE_END_LSN_OLD_CHKSUM); + checksum = checksum & 0xFFFFFFFF; + + return(checksum); +} + +/************************************************************************ +In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only +looked at the first few bytes of the page. This calculates that old +checksum. +NOTE: we must first store the new formula checksum to +FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum +because this takes that field as an input! */ + +ulint +buf_calc_page_old_checksum( +/*=======================*/ + /* out: checksum */ + byte* page) /* in: buffer page */ +{ + ulint checksum; checksum = ut_fold_binary(page, FIL_PAGE_FILE_FLUSH_LSN); - + ut_fold_binary(page + FIL_PAGE_DATA, - UNIV_PAGE_SIZE - FIL_PAGE_DATA - - FIL_PAGE_END_LSN); + checksum = checksum & 0xFFFFFFFF; return(checksum); @@ -243,27 +270,47 @@ buf_page_is_corrupted( byte* read_buf) /* in: a database page */ { ulint checksum; + ulint old_checksum; + ulint checksum_field; + ulint old_checksum_field; - checksum = buf_calc_page_checksum(read_buf); + if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4) + != mach_read_from_4(read_buf + UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { + + /* Stored log sequence numbers at the start and the end + of page do not match */ - /* Note that InnoDB initializes empty pages to zero, and - early versions of InnoDB did not store page checksum to - the 4 most significant bytes of the page lsn field at the - end of a page: */ - - if ((mach_read_from_4(read_buf + FIL_PAGE_LSN + 4) - != mach_read_from_4(read_buf + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN + 4)) - || (checksum != mach_read_from_4(read_buf - + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN) - && mach_read_from_4(read_buf + FIL_PAGE_LSN) - != mach_read_from_4(read_buf - + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN))) { return(TRUE); } + old_checksum = buf_calc_page_old_checksum(read_buf); + + old_checksum_field = mach_read_from_4(read_buf + UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM); + + /* There are 2 valid formulas for old_checksum_field: + 1. Very old versions of InnoDB only stored 8 byte lsn to the start + and the end of the page. + 2. Newer InnoDB versions store the old formula checksum there. */ + + if (old_checksum_field != mach_read_from_4(read_buf + FIL_PAGE_LSN) + && old_checksum_field != old_checksum) { + + return(TRUE); + } + + checksum = buf_calc_page_new_checksum(read_buf); + checksum_field = mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM); + + /* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id + (always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */ + + if (checksum_field != 0 && checksum_field != checksum) { + + return(TRUE); + } + return(FALSE); } @@ -277,6 +324,7 @@ buf_page_print( { dict_index_t* index; ulint checksum; + ulint old_checksum; char* buf; buf = mem_alloc(4 * UNIV_PAGE_SIZE); @@ -291,19 +339,23 @@ buf_page_print( mem_free(buf); - checksum = buf_calc_page_checksum(read_buf); + checksum = buf_calc_page_new_checksum(read_buf); + old_checksum = buf_calc_page_old_checksum(read_buf); ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: Page checksum %lu stored checksum %lu\n", - checksum, mach_read_from_4(read_buf - + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN)); + fprintf(stderr, +" InnoDB: Page checksum %lu, prior-to-4.0.14-form checksum %lu\n" +"InnoDB: stored checksum %lu, prior-to-4.0.14-form stored checksum %lu\n", + checksum, old_checksum, + mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM), + mach_read_from_4(read_buf + UNIV_PAGE_SIZE + - FIL_PAGE_END_LSN_OLD_CHKSUM)); fprintf(stderr, "InnoDB: Page lsn %lu %lu, low 4 bytes of lsn at page end %lu\n", mach_read_from_4(read_buf + FIL_PAGE_LSN), mach_read_from_4(read_buf + FIL_PAGE_LSN + 4), mach_read_from_4(read_buf + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN + 4)); + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)); if (mach_read_from_2(read_buf + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_TYPE) == TRX_UNDO_INSERT) { fprintf(stderr, diff --git a/innobase/buf/buf0flu.c b/innobase/buf/buf0flu.c index 735966c28c5..c0999ee4841 100644 --- a/innobase/buf/buf0flu.c +++ b/innobase/buf/buf0flu.c @@ -361,21 +361,29 @@ buf_flush_init_for_writing( ulint space, /* in: space id */ ulint page_no) /* in: page number */ { - /* Write the newest modification lsn to the page */ + UT_NOT_USED(space); + + /* Write the newest modification lsn to the page header and trailer */ mach_write_to_8(page + FIL_PAGE_LSN, newest_lsn); - mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN, newest_lsn); + mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, + newest_lsn); + /* Write the page number */ - /* Write to the page the space id and page number */ - - mach_write_to_4(page + FIL_PAGE_SPACE, space); mach_write_to_4(page + FIL_PAGE_OFFSET, page_no); - /* We overwrite the first 4 bytes of the end lsn field to store - a page checksum */ + /* Store the new formula checksum */ - mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN, - buf_calc_page_checksum(page)); + mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM, + buf_calc_page_new_checksum(page)); + + /* We overwrite the first 4 bytes of the end lsn field to store + the old formula checksum. Since it depends also on the field + FIL_PAGE_SPACE_OR_CHKSUM, it has to be calculated after storing the + new formula checksum. */ + + mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, + buf_calc_page_old_checksum(page)); } /************************************************************************ diff --git a/innobase/data/data0data.c b/innobase/data/data0data.c index 8ab5acb4da7..f2f94cc47ce 100644 --- a/innobase/data/data0data.c +++ b/innobase/data/data0data.c @@ -584,8 +584,7 @@ dtuple_convert_big_rec( * sizeof(big_rec_field_t)); /* Decide which fields to shorten: the algorithm is to look for - the longest field which does not occur in the ordering part - of any index on the table */ + the longest field whose type is DATA_BLOB */ n_fields = 0; @@ -610,12 +609,9 @@ dtuple_convert_big_rec( } } - /* Skip over fields which are ordering in some index */ - - if (!is_externally_stored && - dict_field_get_col( - dict_index_get_nth_field(index, i)) - ->ord_part == 0) { + if (!is_externally_stored + && dict_index_get_nth_type(index, i)->mtype + == DATA_BLOB) { dfield = dtuple_get_nth_field(entry, i); @@ -629,9 +625,13 @@ dtuple_convert_big_rec( } } - if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10 - + REC_1BYTE_OFFS_LIMIT) { + /* We do not store externally fields which are smaller than + DICT_MAX_COL_PREFIX_LEN */ + ut_a(DICT_MAX_COL_PREFIX_LEN > REC_1BYTE_OFFS_LIMIT); + + if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10 + + DICT_MAX_COL_PREFIX_LEN) { /* Cannot shorten more */ mem_heap_free(heap); @@ -644,13 +644,19 @@ dtuple_convert_big_rec( drop below 128 which is the limit for the 2-byte offset storage format in a physical record. This we accomplish by storing 128 bytes of data in entry - itself, and only the remaining part to big rec vec. */ + itself, and only the remaining part to big rec vec. + + We store the first bytes locally to the record. Then + we can calculate all ordering fields in all indexes + from locally stored data. */ dfield = dtuple_get_nth_field(entry, longest_i); vector->fields[n_fields].field_no = longest_i; + ut_a(dfield->len > DICT_MAX_COL_PREFIX_LEN); + vector->fields[n_fields].len = dfield->len - - REC_1BYTE_OFFS_LIMIT; + - DICT_MAX_COL_PREFIX_LEN; vector->fields[n_fields].data = mem_heap_alloc(heap, vector->fields[n_fields].len); diff --git a/innobase/data/data0type.c b/innobase/data/data0type.c index 5d0ddf3e887..df430f06bcb 100644 --- a/innobase/data/data0type.c +++ b/innobase/data/data0type.c @@ -85,8 +85,6 @@ dtype_print( printf("DATA_MIX_ID"); } else if (prtype == DATA_ENGLISH) { printf("DATA_ENGLISH"); - } else if (prtype == DATA_FINNISH) { - printf("DATA_FINNISH"); } else { printf("prtype %lu", mtype); } diff --git a/innobase/dict/dict0boot.c b/innobase/dict/dict0boot.c index 374c567c3ca..0bf2ace3324 100644 --- a/innobase/dict/dict0boot.c +++ b/innobase/dict/dict0boot.c @@ -276,7 +276,7 @@ dict_boot(void) DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 1); - dict_mem_index_add_field(index, (char *) "NAME", 0); + dict_mem_index_add_field(index, (char *) "NAME", 0, 0); index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLES, MLOG_4BYTES, &mtr); @@ -287,7 +287,7 @@ dict_boot(void) index = dict_mem_index_create((char *) "SYS_TABLES", (char *) "ID_IND", DICT_HDR_SPACE, DICT_UNIQUE, 1); - dict_mem_index_add_field(index, (char *) "ID", 0); + dict_mem_index_add_field(index, (char *) "ID", 0, 0); index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_TABLE_IDS, MLOG_4BYTES, &mtr); @@ -313,8 +313,8 @@ dict_boot(void) (char *) "CLUST_IND", DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2); - dict_mem_index_add_field(index, (char *) "TABLE_ID", 0); - dict_mem_index_add_field(index, (char *) "POS", 0); + dict_mem_index_add_field(index, (char *) "TABLE_ID", 0, 0); + dict_mem_index_add_field(index, (char *) "POS", 0, 0); index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_COLUMNS, MLOG_4BYTES, &mtr); @@ -343,8 +343,8 @@ dict_boot(void) (char *) "CLUST_IND", DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2); - dict_mem_index_add_field(index, (char *) "TABLE_ID", 0); - dict_mem_index_add_field(index, (char *) "ID", 0); + dict_mem_index_add_field(index, (char *) "TABLE_ID", 0, 0); + dict_mem_index_add_field(index, (char *) "ID", 0, 0); index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_INDEXES, MLOG_4BYTES, &mtr); @@ -365,8 +365,8 @@ dict_boot(void) (char *) "CLUST_IND", DICT_HDR_SPACE, DICT_UNIQUE | DICT_CLUSTERED, 2); - dict_mem_index_add_field(index, (char *) "INDEX_ID", 0); - dict_mem_index_add_field(index, (char *) "POS", 0); + dict_mem_index_add_field(index, (char *) "INDEX_ID", 0, 0); + dict_mem_index_add_field(index, (char *) "POS", 0, 0); index->page_no = mtr_read_ulint(dict_hdr + DICT_HDR_FIELDS, MLOG_4BYTES, &mtr); diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c index 3619ac02f4d..9139e589a0a 100644 --- a/innobase/dict/dict0crea.c +++ b/innobase/dict/dict0crea.c @@ -337,7 +337,7 @@ dict_create_index_for_cluster_step( for (i = 0; i < table->n_cols; i++) { col = dict_table_get_nth_col(table, i); - dict_mem_index_add_field(index, col->name, 0); + dict_mem_index_add_field(index, col->name, 0, 0); } (node->cluster)->index = index; @@ -450,9 +450,17 @@ dict_create_sys_fields_tuple( dict_field_t* field; dfield_t* dfield; byte* ptr; + ibool index_contains_column_prefix_field = FALSE; + ulint j; ut_ad(index && heap); + for (j = 0; j < index->n_fields; j++) { + if (dict_index_get_nth_field(index, j)->prefix_len > 0) { + index_contains_column_prefix_field = TRUE; + } + } + field = dict_index_get_nth_field(index, i); sys_fields = dict_sys->sys_fields; @@ -466,11 +474,25 @@ dict_create_sys_fields_tuple( mach_write_to_8(ptr, index->id); dfield_set_data(dfield, ptr, 8); - /* 1: POS ----------------------------*/ + /* 1: POS + PREFIX LENGTH ----------------------------*/ + dfield = dtuple_get_nth_field(entry, 1); ptr = mem_heap_alloc(heap, 4); - mach_write_to_4(ptr, i); + + if (index_contains_column_prefix_field) { + /* If there are column prefix fields in the index, then + we store the number of the field to the 2 HIGH bytes + and the prefix length to the 2 low bytes, */ + + mach_write_to_4(ptr, (i << 16) + field->prefix_len); + } else { + /* Else we store the number of the field to the 2 LOW bytes. + This is to keep the storage format compatible with + InnoDB versions < 4.0.14. */ + + mach_write_to_4(ptr, i); + } dfield_set_data(dfield, ptr, 4); /* 4: COL_NAME -------------------------*/ diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index c11a5f76d94..2fc05b1923f 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -88,15 +88,6 @@ dict_index_remove_from_cache( dict_table_t* table, /* in: table */ dict_index_t* index); /* in, own: index */ /*********************************************************************** -Adds a column to index. */ -UNIV_INLINE -void -dict_index_add_col( -/*===============*/ - dict_index_t* index, /* in: index */ - dict_col_t* col, /* in: column */ - ulint order); /* in: order criterion */ -/*********************************************************************** Copies fields contained in index2 to index1. */ static void @@ -482,8 +473,9 @@ dict_index_get_nth_col_pos( ut_ad(index); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); + col = dict_table_get_nth_col(index->table, n); + if (index->type & DICT_CLUSTERED) { - col = dict_table_get_nth_col(index->table, n); return(col->clust_pos); } @@ -492,9 +484,8 @@ dict_index_get_nth_col_pos( for (pos = 0; pos < n_fields; pos++) { field = dict_index_get_nth_field(index, pos); - col = field->col; - if (dict_col_get_no(col) == n) { + if (col == field->col && field->prefix_len == 0) { return(pos); } @@ -502,7 +493,46 @@ dict_index_get_nth_col_pos( return(ULINT_UNDEFINED); } + +/************************************************************************ +Looks for a matching field in an index. The column and the prefix len have +to be the same. */ + +ulint +dict_index_get_nth_field_pos( +/*=========================*/ + /* out: position in internal representation + of the index; if not contained, returns + ULINT_UNDEFINED */ + dict_index_t* index, /* in: index from which to search */ + dict_index_t* index2, /* in: index */ + ulint n) /* in: field number in index2 */ +{ + dict_field_t* field; + dict_field_t* field2; + ulint n_fields; + ulint pos; + ut_ad(index); + ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); + + field2 = dict_index_get_nth_field(index2, n); + + n_fields = dict_index_get_n_fields(index); + + for (pos = 0; pos < n_fields; pos++) { + field = dict_index_get_nth_field(index, pos); + + if (field->col == field2->col + && field->prefix_len == field2->prefix_len) { + + return(pos); + } + } + + return(ULINT_UNDEFINED); +} + /************************************************************************** Returns a table object, based on table id, and memoryfixes it. */ @@ -622,8 +652,7 @@ dict_table_get( } /************************************************************************** -Returns a table object and increments MySQL open handle count on the table. -*/ +Returns a table object and increments MySQL open handle count on the table. */ dict_table_t* dict_table_get_and_increment_handle_count( @@ -732,11 +761,12 @@ dict_table_add_to_cache( } /* Add table to hash table of tables */ - HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); + HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, + table); /* Add table to hash table of tables based on table id */ HASH_INSERT(dict_table_t, id_hash, dict_sys->table_id_hash, id_fold, - table); + table); /* Add table to LRU list of tables */ UT_LIST_ADD_FIRST(table_LRU, dict_sys->table_LRU, table); @@ -828,7 +858,7 @@ dict_table_rename_in_cache( /* Remove table from the hash tables of tables */ HASH_DELETE(dict_table_t, name_hash, dict_sys->table_hash, - ut_fold_string(table->name), table); + ut_fold_string(table->name), table); name_buf = mem_heap_alloc(table->heap, ut_strlen(new_name) + 1); @@ -837,7 +867,8 @@ dict_table_rename_in_cache( table->name = name_buf; /* Add table to hash table of tables */ - HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, table); + HASH_INSERT(dict_table_t, name_hash, dict_sys->table_hash, fold, + table); dict_sys->size += (mem_heap_get_size(table->heap) - old_size); @@ -1128,7 +1159,6 @@ dict_index_add_to_cache( ulint n_ord; ibool success; ulint i; - ulint j; ut_ad(index); ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1158,28 +1188,6 @@ dict_index_add_to_cache( return(FALSE); } - - /* Check that the same column does not appear twice in the index. - InnoDB assumes this in its algorithms, e.g., update of an index - entry */ - - for (i = 0; i < dict_index_get_n_fields(index); i++) { - - for (j = 0; j < i; j++) { - if (dict_index_get_nth_field(index, j)->col - == dict_index_get_nth_field(index, i)->col) { - - ut_print_timestamp(stderr); - - fprintf(stderr, -" InnoDB: Error: column %s appears twice in index %s of table %s\n" -"InnoDB: This is not allowed in InnoDB.\n" -"InnoDB: UPDATE can cause such an index to become corrupt in InnoDB.\n", - dict_index_get_nth_field(index, i)->col->name, - index->name, table->name); - } - } - } /* Build the cache internal representation of the index, containing also the added system fields */ @@ -1223,8 +1231,8 @@ dict_index_add_to_cache( cluster = dict_table_get_low(table->cluster_name); - tree = dict_index_get_tree(UT_LIST_GET_FIRST(cluster->indexes)); - + tree = dict_index_get_tree( + UT_LIST_GET_FIRST(cluster->indexes)); new_index->tree = tree; new_index->page_no = tree->page; } else { @@ -1352,13 +1360,14 @@ UNIV_INLINE void dict_index_add_col( /*===============*/ - dict_index_t* index, /* in: index */ - dict_col_t* col, /* in: column */ - ulint order) /* in: order criterion */ + dict_index_t* index, /* in: index */ + dict_col_t* col, /* in: column */ + ulint order, /* in: order criterion */ + ulint prefix_len) /* in: column prefix length */ { dict_field_t* field; - dict_mem_index_add_field(index, col->name, order); + dict_mem_index_add_field(index, col->name, order, prefix_len); field = dict_index_get_nth_field(index, index->n_def - 1); @@ -1384,7 +1393,8 @@ dict_index_copy( for (i = start; i < end; i++) { field = dict_index_get_nth_field(index2, i); - dict_index_add_col(index1, field->col, field->order); + dict_index_add_col(index1, field->col, field->order, + field->prefix_len); } } @@ -1487,7 +1497,7 @@ dict_index_build_internal_clust( /* Add the mix id column */ dict_index_add_col(new_index, - dict_table_get_sys_col(table, DATA_MIX_ID), 0); + dict_table_get_sys_col(table, DATA_MIX_ID), 0, 0); /* Copy the rest of fields */ dict_index_copy(new_index, index, table->mix_len, @@ -1525,14 +1535,15 @@ dict_index_build_internal_clust( if (!(index->type & DICT_UNIQUE)) { dict_index_add_col(new_index, - dict_table_get_sys_col(table, DATA_ROW_ID), 0); + dict_table_get_sys_col(table, DATA_ROW_ID), 0, 0); trx_id_pos++; } dict_index_add_col(new_index, - dict_table_get_sys_col(table, DATA_TRX_ID), 0); + dict_table_get_sys_col(table, DATA_TRX_ID), 0, 0); + dict_index_add_col(new_index, - dict_table_get_sys_col(table, DATA_ROLL_PTR), 0); + dict_table_get_sys_col(table, DATA_ROLL_PTR), 0, 0); for (i = 0; i < trx_id_pos; i++) { @@ -1561,7 +1572,14 @@ dict_index_build_internal_clust( for (i = 0; i < new_index->n_def; i++) { field = dict_index_get_nth_field(new_index, i); - (field->col)->aux = 0; + + /* If there is only a prefix of the column in the index + field, do not mark the column as contained in the index */ + + if (field->prefix_len == 0) { + + field->col->aux = 0; + } } /* Add to new_index non-system columns of table not yet included @@ -1572,7 +1590,7 @@ dict_index_build_internal_clust( ut_ad(col->type.mtype != DATA_SYS); if (col->aux == ULINT_UNDEFINED) { - dict_index_add_col(new_index, col, 0); + dict_index_add_col(new_index, col, 0, 0); } } @@ -1584,7 +1602,11 @@ dict_index_build_internal_clust( for (i = 0; i < new_index->n_def; i++) { field = dict_index_get_nth_field(new_index, i); - (field->col)->clust_pos = i; + + if (field->prefix_len == 0) { + + field->col->clust_pos = i; + } } new_index->cached = TRUE; @@ -1646,25 +1668,33 @@ dict_index_build_internal_non_clust( for (i = 0; i < clust_index->n_uniq; i++) { field = dict_index_get_nth_field(clust_index, i); - (field->col)->aux = ULINT_UNDEFINED; + field->col->aux = ULINT_UNDEFINED; } /* Mark with 0 table columns already contained in new_index */ for (i = 0; i < new_index->n_def; i++) { field = dict_index_get_nth_field(new_index, i); - (field->col)->aux = 0; + + /* If there is only a prefix of the column in the index + field, do not mark the column as contained in the index */ + + if (field->prefix_len == 0) { + + field->col->aux = 0; + } } - /* Add to new_index columns necessary to determine the clustered + /* Add to new_index the columns necessary to determine the clustered index entry uniquely */ for (i = 0; i < clust_index->n_uniq; i++) { field = dict_index_get_nth_field(clust_index, i); - if ((field->col)->aux == ULINT_UNDEFINED) { - dict_index_add_col(new_index, field->col, 0); + if (field->col->aux == ULINT_UNDEFINED) { + dict_index_add_col(new_index, field->col, 0, + field->prefix_len); } } @@ -1787,6 +1817,14 @@ dict_foreign_find_index( for (i = 0; i < n_cols; i++) { col_name = dict_index_get_nth_field(index, i) ->col->name; + if (dict_index_get_nth_field(index, i) + ->prefix_len != 0) { + /* We do not accept column prefix + indexes here */ + + break; + } + if (ut_strlen(columns[i]) != ut_strlen(col_name) || 0 != ut_cmp_in_lower_case(columns[i], @@ -3776,6 +3814,10 @@ dict_field_print_low( ut_ad(mutex_own(&(dict_sys->mutex))); printf(" %s", field->name); + + if (field->prefix_len != 0) { + printf("(%lu)", field->prefix_len); + } } /************************************************************************** diff --git a/innobase/dict/dict0load.c b/innobase/dict/dict0load.c index 8f39605e493..48c445fa0c9 100644 --- a/innobase/dict/dict0load.c +++ b/innobase/dict/dict0load.c @@ -301,6 +301,8 @@ dict_load_fields( dtuple_t* tuple; dfield_t* dfield; char* col_name; + ulint pos_and_prefix_len; + ulint prefix_len; rec_t* rec; byte* field; ulint len; @@ -345,8 +347,28 @@ dict_load_fields( ut_a(ut_memcmp(buf, field, len) == 0); field = rec_get_nth_field(rec, 1, &len); - ut_ad(len == 4); - ut_a(i == mach_read_from_4(field)); + ut_a(len == 4); + + /* The next field stores the field position in the index + and a possible column prefix length if the index field + does not contain the whole column. The storage format is + like this: if there is at least one prefix field in the index, + then the HIGH 2 bytes contain the field number (== i) and the + low 2 bytes the prefix length for the field. Otherwise the + field number (== i) is contained in the 2 LOW bytes. */ + + pos_and_prefix_len = mach_read_from_4(field); + + ut_a((pos_and_prefix_len & 0xFFFF) == i + || (pos_and_prefix_len & 0xFFFF0000) == (i << 16)); + + if ((i == 0 && pos_and_prefix_len > 0) + || (pos_and_prefix_len & 0xFFFF0000) > 0) { + + prefix_len = pos_and_prefix_len & 0xFFFF; + } else { + prefix_len = 0; + } ut_a(0 == ut_strcmp((char*) "COL_NAME", dict_field_get_col( @@ -359,7 +381,7 @@ dict_load_fields( ut_memcpy(col_name, field, len); col_name[len] = '\0'; - dict_mem_index_add_field(index, col_name, 0); + dict_mem_index_add_field(index, col_name, 0, prefix_len); btr_pcur_move_to_next_user_rec(&pcur, &mtr); } diff --git a/innobase/dict/dict0mem.c b/innobase/dict/dict0mem.c index e5918c6aeb6..56efc0a0117 100644 --- a/innobase/dict/dict0mem.c +++ b/innobase/dict/dict0mem.c @@ -266,10 +266,13 @@ by the column name may be released only after publishing the index. */ void dict_mem_index_add_field( /*=====================*/ - dict_index_t* index, /* in: index */ - char* name, /* in: column name */ - ulint order) /* in: order criterion; 0 means an ascending - order */ + dict_index_t* index, /* in: index */ + 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 + in a MySQL index like + INDEX (textcol(25)) */ { dict_field_t* field; @@ -282,6 +285,8 @@ dict_mem_index_add_field( field->name = name; field->order = order; + + field->prefix_len = prefix_len; } /************************************************************************** diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index 98980f6c337..a8dc357749c 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -632,7 +632,7 @@ fil_space_create( /* Spaces with an odd id number are reserved to replicate spaces used in log debugging */ - ut_a((purpose == FIL_LOG) || (id % 2 == 0)); + ut_anp((purpose == FIL_LOG) || (id % 2 == 0)); #endif mutex_enter(&(system->mutex)); @@ -1202,8 +1202,8 @@ loop: /* Do aio */ - ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0); + ut_anp(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0); + ut_anp((len % OS_FILE_LOG_BLOCK_SIZE) == 0); /* Queue the aio request */ ret = os_aio(type, mode | wake_later, node->name, node->handle, buf, diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c index ee48288b875..b6941d80e90 100644 --- a/innobase/fsp/fsp0fsp.c +++ b/innobase/fsp/fsp0fsp.c @@ -778,7 +778,7 @@ fsp_init_file_page_low( page[i] = 0xFF; } #endif - mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN, + mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, ut_dulint_zero); mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero); } @@ -2875,7 +2875,7 @@ fseg_free_step( freed yet */ ut_a(descr); - ut_a(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header) + ut_anp(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header) % FSP_EXTENT_SIZE, mtr) == FALSE); inode = fseg_inode_get(header, mtr); diff --git a/innobase/ha/ha0ha.c b/innobase/ha/ha0ha.c index 4489b25ec2b..eb28e15215d 100644 --- a/innobase/ha/ha0ha.c +++ b/innobase/ha/ha0ha.c @@ -293,11 +293,13 @@ ha_print_info( hash_table_t* table) /* in: hash table */ { hash_cell_t* cell; -/* ha_node_t* node; */ - ulint nodes = 0; - ulint cells = 0; +/* + ha_node_t* node; ulint len = 0; ulint max_len = 0; + ulint nodes = 0; +*/ + ulint cells = 0; ulint n_bufs; ulint i; diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index 187afa17047..c07756ab308 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -170,7 +170,7 @@ dropped! So, there seems to be no problem. */ /********************************************************************** Validates the ibuf data structures when the caller owns ibuf_mutex. */ -static + ibool ibuf_validate_low(void); /*===================*/ @@ -484,8 +484,8 @@ ibuf_data_init_for_space( index = dict_mem_index_create(buf, (char *) "CLUST_IND", space, DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,2); - dict_mem_index_add_field(index, (char *) "PAGE_NO", 0); - dict_mem_index_add_field(index, (char *) "TYPES", 0); + dict_mem_index_add_field(index, (char *) "PAGE_NO", 0, 0); + dict_mem_index_add_field(index, (char *) "TYPES", 0, 0); index->page_no = FSP_IBUF_TREE_ROOT_PAGE_NO; @@ -2727,7 +2727,7 @@ reset_bit: /********************************************************************** Validates the ibuf data structures when the caller owns ibuf_mutex. */ -static + ibool ibuf_validate_low(void) /*===================*/ diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h index 1d17c0e952d..506877333c3 100644 --- a/innobase/include/btr0cur.h +++ b/innobase/include/btr0cur.h @@ -690,7 +690,13 @@ and sleep this many microseconds in between */ #define BTR_CUR_RETRY_DELETE_N_TIMES 100 #define BTR_CUR_RETRY_SLEEP_TIME 50000 -/* The reference in a field of which data is stored on a different page */ +/* The reference in a field for which data is stored on a different page. +The reference is at the end of the 'locally' stored part of the field. +'Locally' means storage in the index record. +We store locally a long enough prefix of each column so that we can determine +the ordering parts of each index record without looking into the externally +stored part. */ + /*--------------------------------------*/ #define BTR_EXTERN_SPACE_ID 0 /* space id where stored */ #define BTR_EXTERN_PAGE_NO 4 /* page no where stored */ diff --git a/innobase/include/buf0buf.h b/innobase/include/buf0buf.h index e4d3671586d..2963efd6396 100644 --- a/innobase/include/buf0buf.h +++ b/innobase/include/buf0buf.h @@ -364,11 +364,24 @@ to a file. Note that we must be careful to calculate the same value on 32-bit and 64-bit architectures. */ ulint -buf_calc_page_checksum( -/*===================*/ +buf_calc_page_new_checksum( +/*=======================*/ /* out: checksum */ byte* page); /* in: buffer page */ /************************************************************************ +In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only +looked at the first few bytes of the page. This calculates that old +checksum. +NOTE: we must first store the new formula checksum to +FIL_PAGE_SPACE_OR_CHKSUM before calculating and storing this old checksum +because this takes that field as an input! */ + +ulint +buf_calc_page_old_checksum( +/*=======================*/ + /* out: checksum */ + byte* page); /* in: buffer page */ +/************************************************************************ Checks if a page is corrupt. */ ibool diff --git a/innobase/include/data0data.h b/innobase/include/data0data.h index e0fb06e5018..889d148d3fe 100644 --- a/innobase/include/data0data.h +++ b/innobase/include/data0data.h @@ -453,8 +453,6 @@ struct dfield_struct{ void* data; /* pointer to data */ ulint len; /* data length; UNIV_SQL_NULL if SQL null; */ dtype_t type; /* type of data */ - ulint col_no; /* when building index entries, the column - number can be stored here */ }; struct dtuple_struct { diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index b53a70a8909..5e28f657f0c 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -18,14 +18,16 @@ typedef struct dtype_struct dtype_t; data type */ extern dtype_t* dtype_binary; -/* Data main types of SQL data; NOTE! character data types requiring -collation transformation must have the smallest codes! All codes must be -less than 256! */ +/* Data main types of SQL data */ #define DATA_VARCHAR 1 /* character varying */ #define DATA_CHAR 2 /* fixed length character */ #define DATA_FIXBINARY 3 /* binary string of fixed length */ #define DATA_BINARY 4 /* binary string */ -#define DATA_BLOB 5 /* binary large object */ +#define DATA_BLOB 5 /* binary large object, or a TEXT type; if + prtype & DATA_NONLATIN1 != 0 the data must + be compared by MySQL as a whole field; if + prtype & DATA_BINARY_TYPE == 0, then this is + actually a TEXT column */ #define DATA_INT 6 /* integer: can be any size 1 - 8 bytes */ #define DATA_SYS_CHILD 7 /* address of the child page in node pointer */ #define DATA_SYS 8 /* system column */ @@ -34,35 +36,55 @@ binary strings */ #define DATA_FLOAT 9 #define DATA_DOUBLE 10 #define DATA_DECIMAL 11 /* decimal number stored as an ASCII string */ -#define DATA_VARMYSQL 12 /* data types for which comparisons must be */ -#define DATA_MYSQL 13 /* made by MySQL */ -#define DATA_ERROR 111 /* error value */ -#define DATA_MTYPE_MAX 255 +#define DATA_VARMYSQL 12 /* non-latin1 varying length char */ +#define DATA_MYSQL 13 /* non-latin1 fixed length char */ +#define DATA_MTYPE_MAX 63 /* dtype_store_for_order_and_null_size() + requires the values are <= 63 */ /*-------------------------------------------*/ -/* Precise data types for system columns; NOTE: the values must run -from 0 up in the order given! All codes must be less than 256! */ +/* In the lowest byte in the precise type we store the MySQL type code +(not applicable for system columns). */ + +#define DATA_ENGLISH 4 /* English language character string: this + is a relic from pre-MySQL time and only used + for InnoDB's own system tables */ +#define DATA_ERROR 111 /* another relic from pre-MySQL time */ + +#define DATA_MYSQL_TYPE_MASK 255 /* AND with this mask to extract the MySQL + type from the precise type */ + +/* Precise data types for system columns and the length of those columns; +NOTE: the values must run from 0 up in the order given! All codes must +be less than 256 */ #define DATA_ROW_ID 0 /* row id: a dulint */ #define DATA_ROW_ID_LEN 6 /* stored length for row id */ + #define DATA_TRX_ID 1 /* transaction id: 6 bytes */ #define DATA_TRX_ID_LEN 6 + #define DATA_ROLL_PTR 2 /* rollback data pointer: 7 bytes */ #define DATA_ROLL_PTR_LEN 7 + #define DATA_MIX_ID 3 /* mixed index label: a dulint, stored in a row in a compressed form */ #define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a compressed dulint form) */ #define DATA_N_SYS_COLS 4 /* number of system columns defined above */ +/*-------------------------------------------*/ +/* Flags ORed to the precise data type */ #define DATA_NOT_NULL 256 /* this is ORed to the precise type when the column is declared as NOT NULL */ #define DATA_UNSIGNED 512 /* this id ORed to the precise type when we have an unsigned integer type */ +#define DATA_BINARY_TYPE 1024 /* if the data type is a binary character + string, this is ORed to the precise type: + this only holds for tables created with + >= MySQL-4.0.14 */ +#define DATA_NONLATIN1 2048 /* if the data type is a character string + of a non-latin1 type, this is ORed to the + precise type: this only holds for tables + created with >= MySQL-4.0.14 */ /*-------------------------------------------*/ -/* Precise types of a char or varchar data. All codes must be less than 256! */ -#define DATA_ENGLISH 4 /* English language character string */ -#define DATA_FINNISH 5 /* Finnish */ -#define DATA_PRTYPE_MAX 255 - /* This many bytes we need to store the type information affecting the alphabetical order for a single field and decide the storage size of an SQL null*/ @@ -123,7 +145,7 @@ dtype_get_pad_char( /*===============*/ /* out: padding character code, or ULINT_UNDEFINED if no padding specified */ - dtype_t* type); /* in: typeumn */ + dtype_t* type); /* in: type */ /*************************************************************************** Returns the size of a fixed size data type, 0 if not a fixed size type. */ UNIV_INLINE @@ -150,24 +172,24 @@ dtype_is_fixed_size( /* out: TRUE if fixed size */ dtype_t* type); /* in: type */ /************************************************************************** -Stores to a type the information which determines its alphabetical -ordering. */ +Stores for a type the information which determines its alphabetical ordering +and the storage size of an SQL NULL value. */ UNIV_INLINE void dtype_store_for_order_and_null_size( /*================================*/ byte* buf, /* in: buffer for DATA_ORDER_NULL_TYPE_BUF_SIZE - bytes */ + bytes where we store the info */ dtype_t* type); /* in: type struct */ /************************************************************************** -Reads of a type the stored information which determines its alphabetical -ordering. */ +Reads to a type the stored information which determines its alphabetical +ordering and the storage size of an SQL NULL value. */ UNIV_INLINE void dtype_read_for_order_and_null_size( /*===============================*/ dtype_t* type, /* in: type struct */ - byte* buf); /* in: buffer for type order info */ + byte* buf); /* in: buffer for the stored order info */ /************************************************************************* Validates a data type structure. */ diff --git a/innobase/include/data0type.ic b/innobase/include/data0type.ic index d82d976d076..ddd0b0ae8cc 100644 --- a/innobase/include/data0type.ic +++ b/innobase/include/data0type.ic @@ -110,7 +110,9 @@ dtype_get_pad_char( if (type->mtype == DATA_CHAR || type->mtype == DATA_VARCHAR || type->mtype == DATA_BINARY - || type->mtype == DATA_FIXBINARY) { + || type->mtype == DATA_FIXBINARY + || type->mtype == DATA_MYSQL + || type->mtype == DATA_VARMYSQL) { /* Space is the padding character for all char and binary strings */ @@ -124,39 +126,56 @@ dtype_get_pad_char( } /************************************************************************** -Stores to a type the information which determines its alphabetical -ordering. */ +Stores for a type the information which determines its alphabetical ordering +and the storage size of an SQL NULL value. */ UNIV_INLINE void dtype_store_for_order_and_null_size( /*================================*/ byte* buf, /* in: buffer for DATA_ORDER_NULL_TYPE_BUF_SIZE - bytes */ + bytes where we store the info */ dtype_t* type) /* in: type struct */ { ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE); buf[0] = (byte)(type->mtype & 0xFF); + + if (type->prtype & DATA_BINARY_TYPE) { + buf[0] = buf[0] | 128; + } + + if (type->prtype & DATA_NONLATIN1) { + buf[0] = buf[0] | 64; + } + buf[1] = (byte)(type->prtype & 0xFF); mach_write_to_2(buf + 2, type->len & 0xFFFF); } /************************************************************************** -Reads of a type the stored information which determines its alphabetical -ordering. */ +Reads to a type the stored information which determines its alphabetical +ordering and the storage size of an SQL NULL value. */ UNIV_INLINE void dtype_read_for_order_and_null_size( /*===============================*/ dtype_t* type, /* in: type struct */ - byte* buf) /* in: buffer for type order info */ + byte* buf) /* in: buffer for stored type order info */ { ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE); - type->mtype = buf[0]; + type->mtype = buf[0] & 63; type->prtype = buf[1]; + if (buf[0] & 128) { + type->prtype = type->prtype | DATA_BINARY_TYPE; + } + + if (buf[0] & 64) { + type->prtype = type->prtype | DATA_NONLATIN1; + } + type->len = mach_read_from_2(buf + 2); } diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h index ab7d0caa35c..854b9794c00 100644 --- a/innobase/include/db0err.h +++ b/innobase/include/db0err.h @@ -44,8 +44,10 @@ Created 5/24/1996 Heikki Tuuri #define DB_CORRUPTION 39 /* data structure corruption noticed */ #define DB_COL_APPEARS_TWICE_IN_INDEX 40 /* InnoDB cannot handle an index where same column appears twice */ -#define DB_CANNOT_DROP_CONSTRAINT 40 /* dropping a foreign key constraint +#define DB_CANNOT_DROP_CONSTRAINT 41 /* dropping a foreign key constraint from a table failed */ +#define DB_NO_SAVEPOINT 42 /* no savepoint exists with the given + name */ /* The following are partial failure codes */ #define DB_FAIL 1000 diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index 97486a7c2f6..e88c6a52bcb 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -569,6 +569,19 @@ dict_index_get_nth_col_pos( dict_index_t* index, /* in: index */ ulint n); /* in: column number */ /************************************************************************ +Looks for a matching field in an index. The column and the prefix len has +to be the same. */ + +ulint +dict_index_get_nth_field_pos( +/*=========================*/ + /* out: position in internal representation + of the index; if not contained, returns + ULINT_UNDEFINED */ + dict_index_t* index, /* in: index from which to search */ + dict_index_t* index2, /* in: index */ + ulint n); /* in: field number in index2 */ +/************************************************************************ Looks for column n position in the clustered index. */ ulint diff --git a/innobase/include/dict0mem.h b/innobase/include/dict0mem.h index 0798541cfe0..03dc913a7c9 100644 --- a/innobase/include/dict0mem.h +++ b/innobase/include/dict0mem.h @@ -111,10 +111,13 @@ by the column name may be released only after publishing the index. */ void dict_mem_index_add_field( /*=====================*/ - dict_index_t* index, /* in: index */ - char* name, /* in: column name */ - ulint order); /* in: order criterion; 0 means an ascending - order */ + dict_index_t* index, /* in: index */ + 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 + in a MySQL index like + INDEX (textcol(25)) */ /************************************************************************** Frees an index memory object. */ @@ -158,12 +161,18 @@ struct dict_col_struct{ in some of the functions below */ }; +#define DICT_MAX_COL_PREFIX_LEN 512 + /* 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 */ - ulint order; /* flags for ordering this field: - DICT_DESCEND, ... */ + dict_col_t* col; /* pointer to the table column */ + 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 + prefix in a MySQL index of type, e.g., + INDEX (textcol(25)); must be smaller + than DICT_MAX_COL_PREFIX_LEN */ }; /* Data structure for an index tree */ diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h index 23ef0304b2d..4f78fdb2fd7 100644 --- a/innobase/include/fil0fil.h +++ b/innobase/include/fil0fil.h @@ -43,7 +43,10 @@ struct fil_addr_struct{ extern fil_addr_t fil_addr_null; /* The byte offsets on a file page for various variables */ -#define FIL_PAGE_SPACE 0 /* space id the page belongs to */ +#define FIL_PAGE_SPACE_OR_CHKSUM 0 /* in < MySQL-4.0.14 space id the + page belongs to (== 0) but in later + versions the 'new' checksum of the + page */ #define FIL_PAGE_OFFSET 4 /* page offset inside space */ #define FIL_PAGE_PREV 8 /* if there is a 'natural' predecessor of the page, its offset */ @@ -64,7 +67,7 @@ extern fil_addr_t fil_addr_null; #define FIL_PAGE_DATA 38 /* start of the data on the page */ /* File page trailer */ -#define FIL_PAGE_END_LSN 8 /* the low 4 bytes of this are used +#define FIL_PAGE_END_LSN_OLD_CHKSUM 8 /* the low 4 bytes of this are used to store the page checksum, the last 4 bytes should be identical to the last 4 bytes of FIL_PAGE_LSN */ diff --git a/innobase/include/lock0lock.h b/innobase/include/lock0lock.h index d3b3d55d015..5608ba020b7 100644 --- a/innobase/include/lock0lock.h +++ b/innobase/include/lock0lock.h @@ -450,6 +450,18 @@ lock_rec_get_mutex_for_addr( ulint space, /* in: space id */ ulint page_no);/* in: page number */ /************************************************************************* +Checks that a transaction id is sensible, i.e., not in the future. */ + +ibool +lock_check_trx_id_sanity( +/*=====================*/ + /* out: TRUE if ok */ + dulint trx_id, /* in: trx id */ + rec_t* rec, /* in: user record */ + dict_index_t* index, /* in: clustered index */ + ibool has_kernel_mutex);/* in: TRUE if the caller owns the + kernel mutex */ +/************************************************************************* Validates the lock queue on a single record. */ ibool diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 86f27a2d3eb..1ec8b71d069 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -146,6 +146,21 @@ os_file_create_simple( 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_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 or OS_FILE_READ_WRITE */ + ibool* success);/* out: TRUE if succeed, FALSE if error */ +/******************************************************************** Opens an existing file or creates a new. */ os_file_t @@ -173,6 +188,14 @@ os_file_close( /* out: TRUE if success */ os_file_t file); /* in, own: handle to a file */ /*************************************************************************** +Closes a file handle. */ + +ibool +os_file_close_no_error_handling( +/*============================*/ + /* out: TRUE if success */ + os_file_t file); /* in, own: handle to a file */ +/*************************************************************************** Gets a file size. */ ibool diff --git a/innobase/include/page0page.h b/innobase/include/page0page.h index b5e33af5bc0..04f771c3abd 100644 --- a/innobase/include/page0page.h +++ b/innobase/include/page0page.h @@ -666,6 +666,15 @@ page_rec_validate( /* out: TRUE if ok */ rec_t* rec); /* in: record on the page */ /******************************************************************* +Checks that the first directory slot points to the infimum record and +the last to the supremum. This function is intended to track if the +bug fixed in 4.0.14 has caused corruption to users' databases. */ + +void +page_check_dir( +/*===========*/ + page_t* page); /* in: index page */ +/******************************************************************* This function checks the consistency of an index page when we do not know the index. This is also resilient so that this should never crash even if the page is total garbage. */ diff --git a/innobase/include/rem0cmp.h b/innobase/include/rem0cmp.h index 6f2a99fc8c2..712e263350e 100644 --- a/innobase/include/rem0cmp.h +++ b/innobase/include/rem0cmp.h @@ -42,6 +42,22 @@ cmp_data_data( buffer) */ ulint len2); /* in: data field length or UNIV_SQL_NULL */ /***************************************************************** +This function is used to compare two data fields for which we know the +data type. */ + +int +cmp_data_data_slow( +/*===============*/ + /* out: 1, 0, -1, if data1 is greater, equal, + less than data2, respectively */ + dtype_t* cur_type,/* in: data type of the fields */ + byte* data1, /* in: data field (== a pointer to a memory + buffer) */ + ulint len1, /* in: data field length or UNIV_SQL_NULL */ + byte* data2, /* in: data field (== a pointer to a memory + buffer) */ + ulint len2); /* in: data field length or UNIV_SQL_NULL */ +/***************************************************************** This function is used to compare two dfields where at least the first has its data type field set. */ UNIV_INLINE diff --git a/innobase/include/row0mysql.ic b/innobase/include/row0mysql.ic index e9d493da8b5..4ecd66e06ec 100644 --- a/innobase/include/row0mysql.ic +++ b/innobase/include/row0mysql.ic @@ -58,7 +58,8 @@ row_mysql_store_col_in_innobase_format( /*===================================*/ dfield_t* dfield, /* in/out: dfield */ byte* buf, /* in/out: buffer for the converted - value */ + value; this must be at least col_len + long! */ byte* mysql_data, /* in: MySQL column value, not SQL NULL; NOTE that dfield may also get a pointer to mysql_data, @@ -96,7 +97,6 @@ row_mysql_store_col_in_innobase_format( while (col_len > 0 && ptr[col_len - 1] == ' ') { col_len--; } - } else if (type == DATA_BLOB) { ptr = row_mysql_read_blob_ref(&col_len, mysql_data, col_len); } diff --git a/innobase/include/row0row.h b/innobase/include/row0row.h index 09a79e19fd7..d1befbbbad3 100644 --- a/innobase/include/row0row.h +++ b/innobase/include/row0row.h @@ -86,9 +86,10 @@ dtuple_t* row_build( /*======*/ /* out, own: row built; see the NOTE below! */ - ulint type, /* in: ROW_COPY_DATA, or ROW_COPY_POINTERS: - the former copies also the data fields to - heap as the latter only places pointers to + ulint type, /* in: ROW_COPY_POINTERS, ROW_COPY_DATA, or + ROW_COPY_ALSO_EXTERNALS, + the two last copy also the data fields to + heap as the first only places pointers to data fields on the index page, and thus is more efficient */ dict_index_t* index, /* in: clustered index */ diff --git a/innobase/include/row0sel.h b/innobase/include/row0sel.h index aa2da6fe5f6..5ef7ff9399a 100644 --- a/innobase/include/row0sel.h +++ b/innobase/include/row0sel.h @@ -87,9 +87,11 @@ row_printf_step( /* out: query thread to run next or NULL */ que_thr_t* thr); /* in: query thread */ /******************************************************************** -Converts a key value stored in MySQL format to an Innobase dtuple. -The last field of the key value may be just a prefix of a fixed length -field: hence the parameter key_len. */ +Converts a key value stored in MySQL format to an Innobase dtuple. The last +field of the key value may be just a prefix of a fixed length field: hence +the parameter key_len. But currently we do not allow search keys where the +last field is only a prefix of the full key field len and print a warning if +such appears. */ void row_sel_convert_mysql_key_to_innobase( @@ -100,6 +102,7 @@ row_sel_convert_mysql_key_to_innobase( to index! */ byte* buf, /* in: buffer to use in field conversions */ + ulint buf_len, /* in: buffer length */ dict_index_t* index, /* in: index of the key value */ byte* key_ptr, /* in: MySQL key value */ ulint key_len); /* in: MySQL key value length */ diff --git a/innobase/include/row0upd.h b/innobase/include/row0upd.h index 273ec6074eb..473c55c7ef9 100644 --- a/innobase/include/row0upd.h +++ b/innobase/include/row0upd.h @@ -114,13 +114,15 @@ row_upd_index_write_log( closed within this function */ mtr_t* mtr); /* in: mtr into whose log to write */ /*************************************************************** -Returns TRUE if row update changes size of some field in index. */ +Returns TRUE if row update changes size of some field in index or if some +field to be updated is stored externally in rec or update. */ ibool -row_upd_changes_field_size( -/*=======================*/ +row_upd_changes_field_size_or_external( +/*===================================*/ /* out: TRUE if the update changes the size of - some field in index */ + some field in index or the field is external + in rec or update */ rec_t* rec, /* in: record in clustered index */ dict_index_t* index, /* in: clustered index */ upd_t* update);/* in: update vector */ @@ -175,16 +177,10 @@ row_upd_index_replace_new_col_vals( dtuple_t* entry, /* in/out: index entry where replaced */ dict_index_t* index, /* in: index; NOTE that may also be a non-clustered index */ - upd_t* update); /* in: update vector */ -/*************************************************************** -Replaces the new column values stored in the update vector to the -clustered index entry given. */ - -void -row_upd_clust_index_replace_new_col_vals( -/*=====================================*/ - dtuple_t* entry, /* in/out: index entry where replaced */ - upd_t* update); /* in: update vector */ + upd_t* update, /* in: update vector */ + mem_heap_t* heap); /* in: memory heap to which we allocate and + copy the new values, set this as NULL if you + do not want allocation */ /*************************************************************** Checks if an update vector changes an ordering field of an index record. This function is fast if the update vector is short or the number of ordering @@ -358,9 +354,9 @@ struct upd_node_struct{ externally in the clustered index record of row */ ulint n_ext_vec;/* number of fields in ext_vec */ - mem_heap_t* heap; /* memory heap used as auxiliary storage for - row; this must be emptied after a successful - update if node->row != NULL */ + mem_heap_t* heap; /* memory heap used as auxiliary storage; + this must be emptied after a successful + update */ /*----------------------*/ sym_node_t* table_sym;/* table node in symbol table */ que_node_t* col_assign_list; diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 24e692dedab..1e54d7bfc35 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -153,6 +153,7 @@ extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs, /* Array of English strings describing the current state of an i/o handler thread */ extern char* srv_io_thread_op_info[]; +extern char* srv_io_thread_function[]; typedef struct srv_sys_struct srv_sys_t; diff --git a/innobase/include/trx0roll.h b/innobase/include/trx0roll.h index 820af4cd014..0d7126c9c57 100644 --- a/innobase/include/trx0roll.h +++ b/innobase/include/trx0roll.h @@ -177,6 +177,55 @@ trx_general_rollback_for_mysql( ibool partial,/* in: TRUE if partial rollback requested */ trx_savept_t* savept);/* in: pointer to savepoint undo number, if partial rollback requested */ +/*********************************************************************** +Rolls back a transaction back to a named savepoint. Modifications after the +savepoint are undone but InnoDB does NOT release the corresponding locks +which are stored in memory. If a lock is 'implicit', that is, a new inserted +row holds a lock where the lock information is carried by the trx id stored in +the row, these locks are naturally released in the rollback. Savepoints which +were set after this savepoint are deleted. */ + +ulint +trx_rollback_to_savepoint_for_mysql( +/*================================*/ + /* out: if no savepoint + of the name found then + DB_NO_SAVEPOINT, + otherwise DB_SUCCESS */ + trx_t* trx, /* in: transaction handle */ + 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 + information to remove the + binlog entries of the queries + executed after the savepoint */ +/*********************************************************************** +Creates a named savepoint. If the transaction is not yet started, starts it. +If there is already a savepoint of the same name, this call erases that old +savepoint and replaces it with a new. Savepoints are deleted in a transaction +commit or rollback. */ + +ulint +trx_savepoint_for_mysql( +/*====================*/ + /* out: always DB_SUCCESS */ + trx_t* trx, /* in: transaction handle */ + 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 + savepoint */ +/*********************************************************************** +Frees savepoint structs. */ + +void +trx_roll_savepoints_free( +/*=====================*/ + trx_t* trx, /* in: transaction handle */ + trx_named_savept_t* savep); /* in: free all savepoints > this one; + if this is NULL, free all savepoints + of trx */ extern sess_t* trx_dummy_sess; @@ -207,6 +256,21 @@ struct roll_node_struct{ case of a partial rollback */ }; +/* A savepoint set with SQL's "SAVEPOINT savepoint_id" command */ +struct trx_named_savept_struct{ + char* name; /* savepoint name */ + trx_savept_t savept; /* the undo number corresponding to + the savepoint */ + ib_longlong mysql_binlog_cache_pos; + /* the MySQL binlog cache position + corresponding to this savepoint, not + defined if the MySQL binlogging is not + enabled */ + UT_LIST_NODE_T(trx_named_savept_t) + trx_savepoints; /* the list of savepoints of a + transaction */ +}; + /* Rollback node states */ #define ROLL_NODE_SEND 1 #define ROLL_NODE_WAIT 2 diff --git a/innobase/include/trx0sys.ic b/innobase/include/trx0sys.ic index ada2d8cb19c..343e6d7c2fa 100644 --- a/innobase/include/trx0sys.ic +++ b/innobase/include/trx0sys.ic @@ -296,6 +296,16 @@ trx_is_active( return(FALSE); } + if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) { + + /* There must be corruption: we return TRUE because this + function is only called by lock_clust_rec_some_has_impl() + and row_vers_impl_x_locked_off_kernel() and they have + diagnostic prints in this case */ + + return(TRUE); + } + trx = trx_get_on_id(trx_id); if (trx && (trx->conc_state == TRX_ACTIVE)) { diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index 39229923375..6b08b674db8 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -381,7 +381,8 @@ struct trx_struct{ replication slave, we have here the master binlog name up to which replication has processed; otherwise - this is a pointer to a null character */ + this is a pointer to a null + character */ ib_longlong mysql_master_log_pos; /* if the database server is a MySQL replication slave, this is the @@ -501,6 +502,10 @@ struct trx_struct{ mem_heap_t* read_view_heap; /* memory heap for the read view */ read_view_t* read_view; /* consistent read view or NULL */ /*------------------------------*/ + UT_LIST_BASE_NODE_T(trx_named_savept_t) + trx_savepoints; /* savepoints set with SAVEPOINT ..., + oldest first */ + /*------------------------------*/ mutex_t undo_mutex; /* mutex protecting the fields in this section (down to undo_no_arr), EXCEPT last_sql_stat_start, which can be diff --git a/innobase/include/trx0types.h b/innobase/include/trx0types.h index b8befe7172f..2965eb4451f 100644 --- a/innobase/include/trx0types.h +++ b/innobase/include/trx0types.h @@ -24,6 +24,7 @@ typedef struct trx_undo_inf_struct trx_undo_inf_t; typedef struct trx_purge_struct trx_purge_t; typedef struct roll_node_struct roll_node_t; typedef struct commit_node_struct commit_node_t; +typedef struct trx_named_savept_struct trx_named_savept_t; /* Transaction savepoint */ typedef struct trx_savept_struct trx_savept_t; diff --git a/innobase/include/ut0dbg.h b/innobase/include/ut0dbg.h index e99dc8c09d6..802557099fc 100644 --- a/innobase/include/ut0dbg.h +++ b/innobase/include/ut0dbg.h @@ -50,6 +50,37 @@ extern ulint* ut_dbg_null_ptr; }\ } +/* This can be used if there are % characters in the assertion formula: +if we try to printf the formula gcc would complain of illegal print +format characters */ +#define ut_anp(EXPR)\ +{\ + ulint dbg_i;\ +\ + if (!((ulint)(EXPR) + ut_dbg_zero)) {\ + ut_print_timestamp(stderr);\ + fprintf(stderr,\ + " InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\ + os_thread_pf(os_thread_get_curr_id()), IB__FILE__,\ + (ulint)__LINE__);\ + fprintf(stderr,\ + "\nInnoDB: We intentionally generate a memory trap.\n");\ + fprintf(stderr,\ + "InnoDB: Send a detailed bug report to mysql@lists.mysql.com\n");\ + ut_dbg_stop_threads = TRUE;\ + dbg_i = *(ut_dbg_null_ptr);\ + if (dbg_i) {\ + ut_dbg_null_ptr = NULL;\ + }\ + }\ + if (ut_dbg_stop_threads) {\ + fprintf(stderr,\ + "InnoDB: Thread %lu stopped in file %s line %lu\n",\ + os_thread_pf(os_thread_get_curr_id()), IB__FILE__, (ulint)__LINE__);\ + os_thread_sleep(1000000000);\ + }\ +} + #define ut_error {\ ulint dbg_i;\ ut_print_timestamp(stderr);\ diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index 09e0d800685..4e8566eba1b 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -57,7 +57,7 @@ ut_free( /*====*/ void* ptr); /* in, own: memory block */ /************************************************************************** -Frees all allocated memory not freed yet. */ +Frees in shutdown all allocated memory not freed yet. */ void ut_free_all_mem(void); diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 4bb1d243ed4..fecb1f95c68 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -356,7 +356,7 @@ lock_mutex_enter_kernel(void) } /************************************************************************* -Releses the kernel mutex. This function is used in this module to allow +Releases the kernel mutex. This function is used in this module to allow monitoring the contention degree on the kernel mutex caused by the lock operations. */ UNIV_INLINE @@ -514,6 +514,53 @@ lock_rec_mutex_own_all(void) #endif +/************************************************************************* +Checks that a transaction id is sensible, i.e., not in the future. */ + +ibool +lock_check_trx_id_sanity( +/*=====================*/ + /* out: TRUE if ok */ + dulint trx_id, /* in: trx id */ + rec_t* rec, /* in: user record */ + dict_index_t* index, /* in: clustered index */ + ibool has_kernel_mutex)/* in: TRUE if the caller owns the + kernel mutex */ +{ + char err_buf[500]; + ibool is_ok = TRUE; + + if (!has_kernel_mutex) { + mutex_enter(&kernel_mutex); + } + + /* A sanity check: the trx_id in rec must be smaller than the global + trx id counter */ + + if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) { + rec_sprintf(err_buf, 400, rec); + ut_print_timestamp(stderr); + fprintf(stderr, +"InnoDB: Error: transaction id associated with record\n%s\n" +"InnoDB: in table %s index %s\n" +"InnoDB: is %lu %lu which is higher than the global trx id counter %lu %lu!\n" +"InnoDB: The table is corrupt. You have to do dump + drop + reimport.\n", + err_buf, index->table_name, index->name, + ut_dulint_get_high(trx_id), + ut_dulint_get_low(trx_id), + ut_dulint_get_high(trx_sys->max_trx_id), + ut_dulint_get_low(trx_sys->max_trx_id)); + + is_ok = FALSE; + } + + if (!has_kernel_mutex) { + mutex_exit(&kernel_mutex); + } + + return(is_ok); +} + /************************************************************************* Checks that a record is seen in a consistent read. */ @@ -539,6 +586,15 @@ lock_clust_rec_cons_read_sees( return(TRUE); } + if (!lock_check_trx_id_sanity(trx_id, rec, index, FALSE)) { + /* Trying to get the 'history' of a corrupt record is bound + to fail: let us try to use the record itself in the query */ + fprintf(stderr, +"InnoDB: We try to access the corrupt record in the query anyway.\n"); + + return(TRUE); + } + return(FALSE); } @@ -562,7 +618,9 @@ lock_sec_rec_cons_read_sees( read_view_t* view) /* in: consistent read view */ { dulint max_trx_id; - + + UT_NOT_USED(index); + ut_ad(!(index->type & DICT_CLUSTERED)); ut_ad(page_rec_is_user_rec(rec)); @@ -575,6 +633,16 @@ lock_sec_rec_cons_read_sees( if (ut_dulint_cmp(max_trx_id, view->up_limit_id) >= 0) { + if (!lock_check_trx_id_sanity(max_trx_id, rec, index, FALSE)) { + /* Trying to get the 'history' of a corrupt record is + bound to fail: let us try to use the record itself in + the query */ + fprintf(stderr, +"InnoDB: We try to access the corrupt record in the query anyway.\n"); + + return(TRUE); + } + return(FALSE); } @@ -1569,6 +1637,15 @@ lock_sec_rec_some_has_impl_off_kernel( /* Ok, in this case it is possible that some transaction has an implicit x-lock. We have to look in the clustered index. */ + if (!lock_check_trx_id_sanity(page_get_max_trx_id(page), rec, index, + TRUE)) { + buf_page_print(page); + + /* The page is corrupt: try to avoid a crash by returning + NULL */ + return(NULL); + } + return(row_vers_impl_x_locked_off_kernel(rec, index)); } @@ -2565,7 +2642,7 @@ lock_move_rec_list_start( ulint heap_no; ulint type_mode; - ut_ad(new_page); + ut_a(new_page); lock_mutex_enter_kernel(); @@ -3028,7 +3105,7 @@ lock_deadlock_recursive( we return LOCK_VICTIM_IS_START */ { lock_t* lock; - ulint bit_no; + ulint bit_no = ULINT_UNDEFINED; trx_t* lock_trx; char* err_buf; ulint ret; @@ -3067,6 +3144,7 @@ lock_deadlock_recursive( lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock); } else { ut_ad(lock_get_type(lock) == LOCK_REC); + ut_a(bit_no != ULINT_UNDEFINED); lock = lock_rec_get_prev(lock, bit_no); } diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index e15812e03af..b5ce1a3d97b 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -375,7 +375,7 @@ log_pad_current_log_block(void) log_close(); log_release(); - ut_ad((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE) + ut_anp((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE) == LOG_BLOCK_HDR_SIZE); } @@ -1070,8 +1070,8 @@ log_group_write_buf( ulint i; ut_ad(mutex_own(&(log_sys->mutex))); - ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0); - ut_ad(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); + ut_anp(len % OS_FILE_LOG_BLOCK_SIZE == 0); + ut_anp(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); if (new_data_offset == 0) { write_header = TRUE; @@ -2123,11 +2123,11 @@ log_group_archive( start_lsn = log_sys->archived_lsn; - ut_ad(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); + ut_anp(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); end_lsn = log_sys->next_archived_lsn; - ut_ad(ut_dulint_get_low(end_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); + ut_anp(ut_dulint_get_low(end_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0); buf = log_sys->archive_buf; @@ -2234,7 +2234,7 @@ loop: group->next_archived_file_no = group->archived_file_no + n_files; group->next_archived_offset = next_offset % group->file_size; - ut_ad(group->next_archived_offset % OS_FILE_LOG_BLOCK_SIZE == 0); + ut_anp(group->next_archived_offset % OS_FILE_LOG_BLOCK_SIZE == 0); } /********************************************************* @@ -2429,8 +2429,8 @@ loop: start_lsn = log_sys->archived_lsn; if (calc_new_limit) { - ut_ad(log_sys->archive_buf_size % OS_FILE_LOG_BLOCK_SIZE == 0); - + ut_anp(log_sys->archive_buf_size % OS_FILE_LOG_BLOCK_SIZE + == 0); limit_lsn = ut_dulint_add(start_lsn, log_sys->archive_buf_size); @@ -2916,6 +2916,7 @@ loop: mutex_enter(&kernel_mutex); + /* Check that there are no longer transactions */ if (trx_n_mysql_transactions > 0 || UT_LIST_GET_LEN(trx_sys->trx_list) > 0) { @@ -2924,6 +2925,8 @@ loop: goto loop; } + /* Check that the master thread is suspended */ + if (srv_n_threads_active[SRV_MASTER] != 0) { mutex_exit(&kernel_mutex); @@ -2952,7 +2955,6 @@ loop: } log_archive_all(); - log_make_checkpoint_at(ut_dulint_max, TRUE); mutex_enter(&(log_sys->mutex)); @@ -2961,8 +2963,9 @@ loop: if (ut_dulint_cmp(lsn, log_sys->last_checkpoint_lsn) != 0 || (srv_log_archive_on - && ut_dulint_cmp(lsn, - ut_dulint_add(log_sys->archived_lsn, LOG_BLOCK_HDR_SIZE)) != 0)) { + && ut_dulint_cmp(lsn, + ut_dulint_add(log_sys->archived_lsn, LOG_BLOCK_HDR_SIZE)) + != 0)) { mutex_exit(&(log_sys->mutex)); @@ -2981,10 +2984,22 @@ loop: mutex_exit(&(log_sys->mutex)); + mutex_enter(&kernel_mutex); + /* Check that the master thread has stayed suspended */ + if (srv_n_threads_active[SRV_MASTER] != 0) { + fprintf(stderr, +"InnoDB: Warning: the master thread woke up during shutdown\n"); + + mutex_exit(&kernel_mutex); + + goto loop; + } + mutex_exit(&kernel_mutex); + fil_flush_file_spaces(FIL_TABLESPACE); fil_flush_file_spaces(FIL_LOG); - /* The following fil_write_... will pass the buffer pool: therefore + /* The next fil_write_... will pass the buffer pool: therefore it is essential that the buffer pool has been completely flushed to disk! */ @@ -2993,12 +3008,14 @@ loop: goto loop; } + /* The lock timeout thread should now have exited */ + if (srv_lock_timeout_and_monitor_active) { goto loop; } - /* We now suspend also the InnoDB error monitor thread */ + /* We now let also the InnoDB error monitor thread to exit */ srv_shutdown_state = SRV_SHUTDOWN_LAST_PHASE; @@ -3008,6 +3025,7 @@ loop: } /* Make some checks that the server really is quiet */ + ut_a(srv_n_threads_active[SRV_MASTER] == 0); ut_a(buf_all_freed()); ut_a(0 == ut_dulint_cmp(lsn, log_sys->lsn)); @@ -3016,6 +3034,7 @@ loop: fil_flush_file_spaces(FIL_TABLESPACE); /* Make some checks that the server really is quiet */ + ut_a(srv_n_threads_active[SRV_MASTER] == 0); ut_a(buf_all_freed()); ut_a(0 == ut_dulint_cmp(lsn, log_sys->lsn)); } diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 47833214d15..8e5fe819afb 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -973,7 +973,7 @@ recv_recover_page( ulint space, /* in: space id */ ulint page_no) /* in: page number */ { - buf_block_t* block; + buf_block_t* block = NULL; recv_addr_t* recv_addr; recv_t* recv; byte* buf; @@ -1085,7 +1085,7 @@ recv_recover_page( page_lsn = page_newest_lsn; mach_write_to_8(page + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN, ut_dulint_zero); + - FIL_PAGE_END_LSN_OLD_CHKSUM, ut_dulint_zero); mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero); } @@ -1107,7 +1107,7 @@ recv_recover_page( recv_parse_or_apply_log_rec_body(recv->type, buf, buf + recv->len, page, &mtr); mach_write_to_8(page + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN, + - FIL_PAGE_END_LSN_OLD_CHKSUM, ut_dulint_add(recv->start_lsn, recv->len)); mach_write_to_8(page + FIL_PAGE_LSN, @@ -1132,6 +1132,8 @@ recv_recover_page( mutex_exit(&(recv_sys->mutex)); if (!recover_backup && modification_to_page) { + ut_a(block); + buf_flush_recv_note_modification(block, start_lsn, end_lsn); } @@ -1339,6 +1341,7 @@ loop: mutex_exit(&(recv_sys->mutex)); } +#ifdef UNIV_HOTBACKUP /*********************************************************************** Applies log records in the hash table to a backup. */ @@ -1520,8 +1523,8 @@ recv_check_identical( for (i = 0; i < len; i++) { if (str1[i] != str2[i]) { - fprintf(stderr, "Strings do not match at offset %lu\n", i); - + fprintf(stderr, + "Strings do not match at offset %lu\n", i); ut_print_buf(str1 + i, 16); fprintf(stderr, "\n"); ut_print_buf(str2 + i, 16); @@ -1654,6 +1657,7 @@ recv_compare_spaces_low( recv_compare_spaces(space1, space2, n_pages); } +#endif /*********************************************************************** Tries to parse a single log record and returns its length. */ diff --git a/innobase/mem/mem0pool.c b/innobase/mem/mem0pool.c index 382e505b63f..b004a8c4df7 100644 --- a/innobase/mem/mem0pool.c +++ b/innobase/mem/mem0pool.c @@ -99,6 +99,12 @@ mem_pool_t* mem_comm_pool = NULL; ulint mem_out_of_mem_err_msg_count = 0; +/* We use this counter to check that the mem pool mutex does not leak; +this is to track a strange assertion failure reported at +mysql@lists.mysql.com */ + +ulint mem_n_threads_inside = 0; + /************************************************************************ Reserves the mem pool mutex. */ @@ -328,6 +334,9 @@ mem_area_alloc( n = ut_2_log(ut_max(size + MEM_AREA_EXTRA_SIZE, MEM_AREA_MIN_SIZE)); mutex_enter(&(pool->mutex)); + mem_n_threads_inside++; + + ut_a(mem_n_threads_inside == 1); area = UT_LIST_GET_FIRST(pool->free_list[n]); @@ -338,6 +347,7 @@ mem_area_alloc( /* Out of memory in memory pool: we try to allocate from the operating system with the regular malloc: */ + mem_n_threads_inside--; mutex_exit(&(pool->mutex)); return(ut_malloc(size)); @@ -353,6 +363,16 @@ mem_area_alloc( n); mem_analyze_corruption((byte*)area); + + /* Try to analyze a strange assertion failure reported at + mysql@lists.mysql.com where the free bit IS 1 in the + hex dump above */ + + if (mem_area_get_free(area)) { + fprintf(stderr, +"InnoDB: Probably a race condition because now the area is marked free!\n"); + } + ut_a(0); } @@ -374,6 +394,7 @@ mem_area_alloc( pool->reserved += mem_area_get_size(area); + mem_n_threads_inside--; mutex_exit(&(pool->mutex)); ut_ad(mem_pool_validate(pool)); @@ -495,6 +516,9 @@ mem_area_free( n = ut_2_log(size); mutex_enter(&(pool->mutex)); + mem_n_threads_inside++; + + ut_a(mem_n_threads_inside == 1); if (buddy && mem_area_get_free(buddy) && (size == mem_area_get_size(buddy))) { @@ -518,6 +542,7 @@ mem_area_free( pool->reserved += ut_2_exp(n); + mem_n_threads_inside--; mutex_exit(&(pool->mutex)); mem_area_free(new_ptr, pool); @@ -533,6 +558,7 @@ mem_area_free( pool->reserved -= size; } + mem_n_threads_inside--; mutex_exit(&(pool->mutex)); ut_ad(mem_pool_validate(pool)); @@ -577,7 +603,7 @@ mem_pool_validate( } } - ut_a(free + pool->reserved == pool->size + ut_anp(free + pool->reserved == pool->size - (pool->size % MEM_AREA_MIN_SIZE)); mutex_exit(&(pool->mutex)); diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 2f32b9347dc..612bd534fd1 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -60,6 +60,7 @@ struct os_aio_slot_struct{ ulint pos; /* index of the slot in the aio array */ ibool reserved; /* TRUE if this slot is reserved */ + time_t reservation_time;/* time when reserved */ ulint len; /* length of the block to read or write */ byte* buf; /* buffer used in i/o */ @@ -147,6 +148,12 @@ time_t os_last_printout; ibool os_has_said_disk_full = FALSE; +/* The mutex protecting the following counts of pending pread and pwrite +operations */ +os_mutex_t os_file_count_mutex; +ulint os_file_n_pending_preads = 0; +ulint os_file_n_pending_pwrites = 0; + /*************************************************************************** Gets the operating system version. Currently works only on Windows. */ @@ -364,6 +371,8 @@ os_io_init_simple(void) { ulint i; + os_file_count_mutex = os_mutex_create(NULL); + for (i = 0; i < OS_FILE_N_SEEK_MUTEXES; i++) { os_file_seek_mutexes[i] = os_mutex_create(NULL); } @@ -415,9 +424,8 @@ try_again: file = CreateFile(name, access, - FILE_SHARE_READ | FILE_SHARE_WRITE, - /* file can be read and written - also by other processes */ + FILE_SHARE_READ,/* file can be read also by other + processes */ NULL, /* default security attributes */ create_flag, attributes, @@ -481,6 +489,101 @@ try_again: return(file); #endif } + +/******************************************************************** +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_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 or OS_FILE_READ_WRITE */ + ibool* success)/* out: TRUE if succeed, FALSE if error */ +{ +#ifdef __WIN__ + os_file_t file; + DWORD create_flag; + DWORD access; + DWORD attributes = 0; + + ut_a(name); + + if (create_mode == OS_FILE_OPEN) { + create_flag = OPEN_EXISTING; + } else if (create_mode == OS_FILE_CREATE) { + create_flag = CREATE_NEW; + } else { + create_flag = 0; + ut_error; + } + + if (access_type == OS_FILE_READ_ONLY) { + access = GENERIC_READ; + } else if (access_type == OS_FILE_READ_WRITE) { + access = GENERIC_READ | GENERIC_WRITE; + } else { + access = 0; + ut_error; + } + + file = CreateFile(name, + access, + FILE_SHARE_READ,/* file can be read also by other + processes */ + NULL, /* default security attributes */ + create_flag, + attributes, + NULL); /* no template file */ + + if (file == INVALID_HANDLE_VALUE) { + *success = FALSE; + } else { + *success = TRUE; + } + + return(file); +#else + os_file_t file; + int create_flag; + + ut_a(name); + + if (create_mode == OS_FILE_OPEN) { + if (access_type == OS_FILE_READ_ONLY) { + create_flag = O_RDONLY; + } else { + create_flag = O_RDWR; + } + } else if (create_mode == OS_FILE_CREATE) { + create_flag = O_RDWR | O_CREAT | O_EXCL; + } else { + create_flag = 0; + ut_error; + } + + if (create_mode == OS_FILE_CREATE) { + file = open(name, create_flag, S_IRUSR | S_IWUSR + | S_IRGRP | S_IWGRP); + } else { + file = open(name, create_flag); + } + + if (file == -1) { + *success = FALSE; + } else { + *success = TRUE; + } + + return(file); +#endif +} + /******************************************************************** Opens an existing file or creates a new. */ @@ -566,9 +669,14 @@ try_again: file = CreateFile(name, GENERIC_READ | GENERIC_WRITE, /* read and write access */ - FILE_SHARE_READ | FILE_SHARE_WRITE, - /* file can be read and written - also by other processes */ + FILE_SHARE_READ,/* File can be read also by other + processes; we must give the read + permission because of ibbackup. We do + not give the write permission to + others because if one would succeed to + start 2 instances of mysqld on the + SAME files, that could cause severe + database corruption! */ NULL, /* default security attributes */ create_flag, attributes, @@ -676,6 +784,41 @@ os_file_close( #endif } +/*************************************************************************** +Closes a file handle. */ + +ibool +os_file_close_no_error_handling( +/*============================*/ + /* out: TRUE if success */ + os_file_t file) /* in, own: handle to a file */ +{ +#ifdef __WIN__ + BOOL ret; + + ut_a(file); + + ret = CloseHandle(file); + + if (ret) { + return(TRUE); + } + + return(FALSE); +#else + int ret; + + ret = close(file); + + if (ret == -1) { + + return(FALSE); + } + + return(TRUE); +#endif +} + /*************************************************************************** Gets a file size. */ @@ -896,6 +1039,7 @@ os_file_pread( offset */ { off_t offs; + ssize_t n_bytes; ut_a((offset & 0xFFFFFFFF) == offset); @@ -917,7 +1061,17 @@ os_file_pread( os_n_file_reads++; #ifdef HAVE_PREAD - return(pread(file, buf, n, offs)); + os_mutex_enter(os_file_count_mutex); + os_file_n_pending_preads++; + os_mutex_exit(os_file_count_mutex); + + n_bytes = pread(file, buf, n, offs); + + os_mutex_enter(os_file_count_mutex); + os_file_n_pending_preads--; + os_mutex_exit(os_file_count_mutex); + + return(n_bytes); #else { ssize_t ret; @@ -982,8 +1136,16 @@ os_file_pwrite( os_n_file_writes++; #ifdef HAVE_PWRITE + os_mutex_enter(os_file_count_mutex); + os_file_n_pending_pwrites++; + os_mutex_exit(os_file_count_mutex); + ret = pwrite(file, buf, n, offs); + os_mutex_enter(os_file_count_mutex); + os_file_n_pending_pwrites--; + os_mutex_exit(os_file_count_mutex); + if (srv_unix_file_flush_method != SRV_UNIX_LITTLESYNC && srv_unix_file_flush_method != SRV_UNIX_NOSYNC && !os_do_not_call_flush_at_each_write) { @@ -1372,20 +1534,36 @@ os_aio_init( os_io_init_simple(); + for (i = 0; i < n_segments; i++) { + srv_io_thread_op_info[i] = (char*)"not started yet"; + } + n_per_seg = n / n_segments; n_write_segs = (n_segments - 2) / 2; n_read_segs = n_segments - 2 - n_write_segs; /* printf("Array n per seg %lu\n", n_per_seg); */ - os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg, - n_read_segs); - os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg, - n_write_segs); os_aio_ibuf_array = os_aio_array_create(n_per_seg, 1); + srv_io_thread_function[0] = (char*)"insert buffer thread"; + os_aio_log_array = os_aio_array_create(n_per_seg, 1); + srv_io_thread_function[1] = (char*)"log thread"; + + os_aio_read_array = os_aio_array_create(n_read_segs * n_per_seg, + n_read_segs); + for (i = 2; i < 2 + n_read_segs; i++) { + srv_io_thread_function[i] = (char*)"read thread"; + } + + os_aio_write_array = os_aio_array_create(n_write_segs * n_per_seg, + n_write_segs); + for (i = 2 + n_read_segs; i < n_segments; i++) { + srv_io_thread_function[i] = (char*)"write thread"; + } + os_aio_sync_array = os_aio_array_create(n_slots_sync, 1); os_aio_n_segments = n_segments; @@ -1677,6 +1855,7 @@ loop: } slot->reserved = TRUE; + slot->reservation_time = time(NULL); slot->message1 = message1; slot->message2 = message2; slot->file = file; @@ -2249,6 +2428,8 @@ os_aio_simulated_handle( ulint total_len; ulint offs; ulint lowest_offset; + ulint biggest_age; + ulint age; byte* combined_buf; byte* combined_buf2= 0; /* Remove warning */ ibool ret; @@ -2301,22 +2482,55 @@ restart: n_consecutive = 0; - /* Look for an i/o request at the lowest offset in the array - (we ignore the high 32 bits of the offset in these heuristics) */ + /* If there are at least 2 seconds old requests, then pick the oldest + one to prevent starvation. If several requests have the same age, + then pick the one at the lowest offset. */ + biggest_age = 0; lowest_offset = ULINT_MAX; - + for (i = 0; i < n; i++) { slot = os_aio_array_get_nth_slot(array, i + segment * n); - if (slot->reserved && slot->offset < lowest_offset) { + if (slot->reserved) { + age = (ulint)difftime(time(NULL), + slot->reservation_time); - /* Found an i/o request */ - consecutive_ios[0] = slot; + if ((age >= 2 && age > biggest_age) + || (age >= 2 && age == biggest_age + && slot->offset < lowest_offset)) { - n_consecutive = 1; + /* Found an i/o request */ + consecutive_ios[0] = slot; - lowest_offset = slot->offset; + n_consecutive = 1; + + biggest_age = age; + lowest_offset = slot->offset; + } + } + } + + if (n_consecutive == 0) { + /* There were no old requests. Look for an i/o request at the + lowest offset in the array (we ignore the high 32 bits of the + offset in these heuristics) */ + + lowest_offset = ULINT_MAX; + + for (i = 0; i < n; i++) { + slot = os_aio_array_get_nth_slot(array, + i + segment * n); + + if (slot->reserved && slot->offset < lowest_offset) { + + /* Found an i/o request */ + consecutive_ios[0] = slot; + + n_consecutive = 1; + + lowest_offset = slot->offset; + } } } @@ -2422,7 +2636,7 @@ consecutive_loop: + FIL_PAGE_LSN + 4) != mach_read_from_4(combined_buf + len2 + UNIV_PAGE_SIZE - - FIL_PAGE_END_LSN + 4)) { + - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: ERROR: The page to be written seems corrupt!\n"); @@ -2583,14 +2797,15 @@ os_aio_print( double avg_bytes_read; ulint i; - if (buf_end - buf < 1000) { + if (buf_end - buf < 1200) { return; } for (i = 0; i < srv_n_file_io_threads; i++) { - buf += sprintf(buf, "I/O thread %lu state: %s\n", i, - srv_io_thread_op_info[i]); + buf += sprintf(buf, "I/O thread %lu state: %s (%s)\n", i, + srv_io_thread_op_info[i], + srv_io_thread_function[i]); } buf += sprintf(buf, "Pending normal aio reads:"); @@ -2665,6 +2880,12 @@ loop: "%lu OS file reads, %lu OS file writes, %lu OS fsyncs\n", os_n_file_reads, os_n_file_writes, os_n_fsyncs); + if (os_file_n_pending_preads != 0 || os_file_n_pending_pwrites != 0) { + buf += sprintf(buf, + "%lu pending preads, %lu pending pwrites\n", + os_file_n_pending_preads, os_file_n_pending_pwrites); + } + if (os_n_file_reads == os_n_file_reads_old) { avg_bytes_read = 0.0; } else { diff --git a/innobase/os/os0thread.c b/innobase/os/os0thread.c index 9af98760ad1..1252cc5e4b7 100644 --- a/innobase/os/os0thread.c +++ b/innobase/os/os0thread.c @@ -187,8 +187,8 @@ os_thread_exit( is cast as a DWORD */ { #ifdef UNIV_DEBUG_THREAD_CREATION - printf("A thread exits.\n"); - printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id())); + printf("Thread exits, id %lu\n", + os_thread_pf(os_thread_get_curr_id())); #endif os_mutex_enter(os_sync_mutex); os_thread_count--; diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c index d3a40668c4b..7e2fc19c00f 100644 --- a/innobase/page/page0cur.c +++ b/innobase/page/page0cur.c @@ -14,6 +14,7 @@ Created 10/4/1994 Heikki Tuuri #include "rem0cmp.h" #include "mtr0log.h" #include "log0recv.h" +#include "rem0cmp.h" ulint page_cur_short_succ = 0; @@ -218,6 +219,8 @@ page_cur_search_with_match( || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE) || (mode == PAGE_CUR_LE_OR_EXTENDS) || (mode == PAGE_CUR_DBG)); + page_check_dir(page); + #ifdef PAGE_CUR_ADAPT if ((page_header_get_field(page, PAGE_LEVEL) == 0) && (mode == PAGE_CUR_LE) @@ -595,6 +598,7 @@ page_cur_parse_insert_rec( rec_t* cursor_rec; byte buf1[1024]; byte* buf; + byte* ptr2 = ptr; ulint info_bits = 0; /* remove warning */ page_cur_t cursor; @@ -697,7 +701,20 @@ page_cur_parse_insert_rec( /* Build the inserted record to buf */ - ut_a(mismatch_index < UNIV_PAGE_SIZE); + if (mismatch_index >= UNIV_PAGE_SIZE) { + printf("Is short %lu, info_bits %lu, offset %lu, o_offset %lu\n" + "mismatch index %lu, end_seg_len %lu\n" + "parsed len %lu\n", + is_short, info_bits, offset, origin_offset, + mismatch_index, end_seg_len, (ulint)(ptr - ptr2)); + + printf("Dump of 300 bytes of log:\n"); + ut_print_buf(ptr2, 300); + + buf_page_print(page); + + ut_a(0); + } ut_memcpy(buf, rec_get_start(cursor_rec), mismatch_index); ut_memcpy(buf + mismatch_index, ptr, end_seg_len); diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index 7d240bdd5b0..ef5dad60c08 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -353,7 +353,7 @@ page_create( infimum_rec = rec_convert_dtuple_to_rec(heap_top, tuple); - ut_ad(infimum_rec == page + PAGE_INFIMUM); + ut_a(infimum_rec == page + PAGE_INFIMUM); rec_set_n_owned(infimum_rec, 1); rec_set_heap_no(infimum_rec, 0); @@ -370,7 +370,7 @@ page_create( supremum_rec = rec_convert_dtuple_to_rec(heap_top, tuple); - ut_ad(supremum_rec == page + PAGE_SUPREMUM); + ut_a(supremum_rec == page + PAGE_SUPREMUM); rec_set_n_owned(supremum_rec, 1); rec_set_heap_no(supremum_rec, 1); @@ -389,6 +389,8 @@ page_create( page_header_set_ptr(page, PAGE_FREE, NULL); page_header_set_field(page, PAGE_GARBAGE, 0); page_header_set_ptr(page, PAGE_LAST_INSERT, NULL); + page_header_set_field(page, PAGE_DIRECTION, PAGE_NO_DIRECTION); + page_header_set_field(page, PAGE_N_DIRECTION, 0); page_header_set_field(page, PAGE_N_RECS, 0); page_set_max_trx_id(page, ut_dulint_zero); @@ -402,17 +404,22 @@ page_create( slot = page_dir_get_nth_slot(page, 1); page_dir_slot_set_rec(slot, supremum_rec); - /* Set next pointers in infimum and supremum */ + /* Set the next pointers in infimum and supremum */ rec_set_next_offs(infimum_rec, (ulint)(supremum_rec - page)); rec_set_next_offs(supremum_rec, 0); +#ifdef notdefined + /* Disable the use of page_template: there is a race condition here: + while one thread is creating page_template, another one can start + using it before the memcpy completes! */ + if (page_template == NULL) { page_template = mem_alloc(UNIV_PAGE_SIZE); ut_memcpy(page_template, page, UNIV_PAGE_SIZE); } - +#endif return(page); } @@ -439,6 +446,9 @@ page_copy_rec_list_end_no_locks( page_cur_move_to_next(&cur1); } + /* Track a memory corruption bug in Windows */ + ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == PAGE_INFIMUM); + page_cur_set_before_first(new_page, &cur2); /* Copy records from the original page to the new page */ @@ -449,6 +459,8 @@ page_copy_rec_list_end_no_locks( ut_a( page_cur_rec_insert(&cur2, page_cur_get_rec(&cur1), mtr)); + ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) + == PAGE_INFIMUM); page_cur_move_to_next(&cur1); page_cur_move_to_next(&cur2); } @@ -1315,6 +1327,37 @@ page_rec_validate( return(TRUE); } + +/******************************************************************* +Checks that the first directory slot points to the infimum record and +the last to the supremum. This function is intended to track if the +bug fixed in 4.0.14 has caused corruption to users' databases. */ + +void +page_check_dir( +/*===========*/ + page_t* page) /* in: index page */ +{ + ulint n_slots; + + n_slots = page_dir_get_n_slots(page); + + if (page_dir_slot_get_rec(page_dir_get_nth_slot(page, 0)) + != page_get_infimum_rec(page)) { + + fprintf(stderr, +"InnoDB: Page directory corruption: supremum not pointed to\n"); + buf_page_print(page); + } + + if (page_dir_slot_get_rec(page_dir_get_nth_slot(page, n_slots - 1)) + != page_get_supremum_rec(page)) { + + fprintf(stderr, +"InnoDB: Page directory corruption: supremum not pointed to\n"); + buf_page_print(page); + } +} /******************************************************************* This function checks the consistency of an index page when we do not @@ -1598,7 +1641,8 @@ page_validate( "InnoDB: previous record %s\n", err_buf); rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record %s\n", err_buf); + fprintf(stderr, + "InnoDB: record %s\n", err_buf); goto func_exit; } diff --git a/innobase/pars/pars0opt.c b/innobase/pars/pars0opt.c index 91083e6fa16..4faf83b47a3 100644 --- a/innobase/pars/pars0opt.c +++ b/innobase/pars/pars0opt.c @@ -1058,7 +1058,6 @@ opt_clust_access( dfield_t* dfield; mem_heap_t* heap; ulint n_fields; - ulint col_no; ulint pos; ulint i; @@ -1093,8 +1092,7 @@ opt_clust_access( plan->clust_map = mem_heap_alloc(heap, n_fields * sizeof(ulint)); for (i = 0; i < n_fields; i++) { - col_no = dict_index_get_nth_col_no(clust_index, i); - pos = dict_index_get_nth_col_pos(index, col_no); + pos = dict_index_get_nth_field_pos(index, clust_index, i); *(plan->clust_map + i) = pos; @@ -1109,7 +1107,8 @@ opt_clust_access( dfield = dtuple_get_nth_field(plan->clust_ref, table->mix_len); - dfield_set_data(dfield, mem_heap_alloc(heap, table->mix_id_len), + dfield_set_data(dfield, mem_heap_alloc(heap, + table->mix_id_len), table->mix_id_len); ut_memcpy(dfield_get_data(dfield), table->mix_id_buf, table->mix_id_len); diff --git a/innobase/pars/pars0pars.c b/innobase/pars/pars0pars.c index 664f498ef3e..3e43b6ae262 100644 --- a/innobase/pars/pars0pars.c +++ b/innobase/pars/pars0pars.c @@ -244,13 +244,11 @@ pars_resolve_func_data_type( /* Inherit the data type from the first argument (which must not be the SQL null literal whose type is DATA_ERROR) */ - ut_a(dtype_get_mtype(que_node_get_data_type(arg)) - != DATA_ERROR); dtype_copy(que_node_get_data_type(node), que_node_get_data_type(arg)); - ut_a(dtype_get_mtype(que_node_get_data_type(node)) == DATA_INT); - + ut_a(dtype_get_mtype(que_node_get_data_type(node)) + == DATA_INT); } else if (func == PARS_COUNT_TOKEN) { ut_a(arg); dtype_set(que_node_get_data_type(node), DATA_INT, 0, 4, 0); @@ -1596,7 +1594,7 @@ pars_create_index( column = column_list; while (column) { - dict_mem_index_add_field(index, column->name, 0); + dict_mem_index_add_field(index, column->name, 0, 0); column->resolved = TRUE; column->token_type = SYM_COLUMN; diff --git a/innobase/rem/rem0cmp.c b/innobase/rem/rem0cmp.c index e9740d7ea78..2e18e68ec43 100644 --- a/innobase/rem/rem0cmp.c +++ b/innobase/rem/rem0cmp.c @@ -38,7 +38,7 @@ Used in debug checking of cmp_dtuple_... . This function is used to compare a data tuple to a physical record. If dtuple has n fields then rec must have either m >= n fields, or it must differ from dtuple in some of the m fields rec has. */ -static + int cmp_debug_dtuple_rec_with_match( /*============================*/ @@ -50,9 +50,10 @@ cmp_debug_dtuple_rec_with_match( dtuple in some of the common fields, or which has an equal number or more fields than dtuple */ - ulint* matched_fields);/* in/out: number of already completely - matched fields; when function returns, - contains the value for current comparison */ + ulint* matched_fields);/* in/out: number of already + completely matched fields; when function + returns, contains the value for current + comparison */ /***************************************************************** This function is used to compare two data fields for which the data type is such that we must use MySQL code to compare them. The prototype here @@ -79,17 +80,12 @@ UNIV_INLINE ulint cmp_collate( /*========*/ - /* out: collation order position */ - dtype_t* type __attribute__((unused)) , /* in: type */ - ulint code) /* in: code of a character stored in database - record */ -{ - ut_ad((type->mtype == DATA_CHAR) || (type->mtype == DATA_VARCHAR)); - + /* out: collation order position */ + ulint code) /* in: code of a character stored in database record */ +{ return((ulint) srv_latin1_ordering[code]); } - /***************************************************************** Returns TRUE if two types are equal for comparison purposes. */ @@ -118,7 +114,8 @@ cmp_types_are_equal( if (type1->mtype == DATA_INT && (type1->prtype & DATA_UNSIGNED) - != (type2->prtype & DATA_UNSIGNED)) { + != (type2->prtype & DATA_UNSIGNED)) { + /* The storage format of an unsigned integer is different from a signed integer: in a signed integer we OR 0x8000... to the value of positive integers. */ @@ -131,12 +128,17 @@ cmp_types_are_equal( return(FALSE); } + if (type1->mtype == DATA_BLOB && (type1->prtype & DATA_BINARY_TYPE) + != (type2->prtype & DATA_BINARY_TYPE)) { + return(FALSE); + } + return(TRUE); } /***************************************************************** -Innobase uses this function is to compare two data fields for which the -data type is such that we must compare whole fields. */ +Innobase uses this function to compare two data fields for which the data type +is such that we must compare whole fields or call MySQL to do the comparison */ static int cmp_whole_field( @@ -239,8 +241,34 @@ cmp_whole_field( return(0); case DATA_VARMYSQL: case DATA_MYSQL: + case DATA_BLOB: + if (data_type == DATA_BLOB + && 0 != (type->prtype & DATA_BINARY_TYPE)) { + + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: comparing a binary BLOB with a character set sensitive\n" +"InnoDB: comparison!\n"); + } + + /* MySQL does not pad the ends of strings with spaces in a + comparison. That would cause a foreign key check to fail for + non-latin1 character sets if we have different length columns. + To prevent that we remove trailing spaces here before doing + the comparison. NOTE that if we in the future map more MySQL + types to DATA_MYSQL or DATA_VARMYSQL, we have to change this + code. */ + + while (a_length > 0 && a[a_length - 1] == ' ') { + a_length--; + } + + while (b_length > 0 && b[b_length - 1] == ' ') { + b_length--; + } + return(innobase_mysql_cmp( - (int)(type->prtype & ~DATA_NOT_NULL), + (int)(type->prtype & DATA_MYSQL_TYPE_MASK), a, a_length, b, b_length)); default: fprintf(stderr, @@ -291,7 +319,10 @@ cmp_data_data_slow( return(1); } - if (cur_type->mtype >= DATA_FLOAT) { + if (cur_type->mtype >= DATA_FLOAT + || (cur_type->mtype == DATA_BLOB + && (cur_type->prtype & DATA_NONLATIN1))) { + return(cmp_whole_field(cur_type, data1, len1, data2, len2)); } @@ -334,9 +365,12 @@ cmp_data_data_slow( goto next_byte; } - if (cur_type->mtype <= DATA_CHAR) { - data1_byte = cmp_collate(cur_type, data1_byte); - data2_byte = cmp_collate(cur_type, data2_byte); + if (cur_type->mtype <= DATA_CHAR + || (cur_type->mtype == DATA_BLOB + && 0 == (cur_type->prtype & DATA_BINARY_TYPE))) { + + data1_byte = cmp_collate(data1_byte); + data2_byte = cmp_collate(data2_byte); } if (data1_byte > data2_byte) { @@ -487,7 +521,9 @@ cmp_dtuple_rec_with_match( } } - if (cur_type->mtype >= DATA_FLOAT) { + if (cur_type->mtype >= DATA_FLOAT + || (cur_type->mtype == DATA_BLOB + && (cur_type->prtype & DATA_NONLATIN1))) { ret = cmp_whole_field(cur_type, dfield_get_data(dtuple_field), dtuple_f_len, @@ -547,10 +583,13 @@ cmp_dtuple_rec_with_match( goto next_byte; } - if (cur_type->mtype <= DATA_CHAR) { - rec_byte = cmp_collate(cur_type, rec_byte); - dtuple_byte = cmp_collate(cur_type, - dtuple_byte); + if (cur_type->mtype <= DATA_CHAR + || (cur_type->mtype == DATA_BLOB + && 0 == + (cur_type->prtype & DATA_BINARY_TYPE))) { + + rec_byte = cmp_collate(rec_byte); + dtuple_byte = cmp_collate(dtuple_byte); } if (dtuple_byte > rec_byte) { @@ -583,8 +622,8 @@ order_resolved: matched_fields)); ut_ad(*matched_fields == cur_field); /* In the debug version, the above cmp_debug_... sets - *matched_fields to a value */ - *matched_fields = cur_field; + *matched_fields to a value */ + *matched_fields = cur_field; *matched_bytes = cur_bytes; return(ret); @@ -804,7 +843,10 @@ cmp_rec_rec_with_match( } } - if (cur_type->mtype >= DATA_FLOAT) { + if (cur_type->mtype >= DATA_FLOAT + || (cur_type->mtype == DATA_BLOB + && (cur_type->prtype & DATA_NONLATIN1))) { + ret = cmp_whole_field(cur_type, rec1_b_ptr, rec1_f_len, rec2_b_ptr, rec2_f_len); @@ -861,9 +903,13 @@ cmp_rec_rec_with_match( goto next_byte; } - if (cur_type->mtype <= DATA_CHAR) { - rec1_byte = cmp_collate(cur_type, rec1_byte); - rec2_byte = cmp_collate(cur_type, rec2_byte); + if (cur_type->mtype <= DATA_CHAR + || (cur_type->mtype == DATA_BLOB + && 0 == + (cur_type->prtype & DATA_BINARY_TYPE))) { + + rec1_byte = cmp_collate(rec1_byte); + rec2_byte = cmp_collate(rec2_byte); } if (rec1_byte < rec2_byte) { @@ -906,7 +952,7 @@ This function is used to compare a data tuple to a physical record. If dtuple has n fields then rec must have either m >= n fields, or it must differ from dtuple in some of the m fields rec has. If encounters an externally stored field, returns 0. */ -static + int cmp_debug_dtuple_rec_with_match( /*============================*/ @@ -918,9 +964,10 @@ cmp_debug_dtuple_rec_with_match( dtuple in some of the common fields, or which has an equal number or more fields than dtuple */ - ulint* matched_fields) /* in/out: number of already completely - matched fields; when function returns, - contains the value for current comparison */ + ulint* matched_fields) /* in/out: number of already + completely matched fields; when function + returns, contains the value for current + comparison */ { dtype_t* cur_type; /* pointer to type of the current field in dtuple */ diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index e96c08a715b..23da0b9b93c 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -217,8 +217,8 @@ ins_node_set_new_row( } /*********************************************************************** -Does an insert operation by updating a delete marked existing record -in the index. This situation can occur if the delete marked record is +Does an insert operation by updating a delete-marked existing record +in the index. This situation can occur if the delete-marked record is kept in the index for consistent reads. */ static ulint @@ -240,9 +240,9 @@ row_ins_sec_index_entry_by_modify( ut_ad((cursor->index->type & DICT_CLUSTERED) == 0); ut_ad(rec_get_deleted_flag(rec)); - /* We know that in the ordering entry and rec are identified. - But in their binary form there may be differences if there - are char fields in them. Therefore we have to calculate the + /* We know that in the alphabetical ordering, entry and rec are + identical. But in their binary form there may be differences if + there are char fields in them. Therefore we have to calculate the difference and do an update-in-place if necessary. */ heap = mem_heap_create(1024); @@ -305,8 +305,8 @@ row_ins_clust_index_entry_by_modify( /* Try optimistic updating of the record, keeping changes within the page */ - err = btr_cur_optimistic_update(0, cursor, update, 0, thr, mtr); - + err = btr_cur_optimistic_update(0, cursor, update, 0, thr, + mtr); if (err == DB_OVERFLOW || err == DB_UNDERFLOW) { err = DB_FAIL; } @@ -364,11 +364,17 @@ row_ins_cascade_calc_update_vec( /* out: number of fields in the calculated update vector; the value can also be 0 if no foreign key - fields changed */ + fields changed; the returned value + is ULINT_UNDEFINED if the column + type in the child table is too short + to fit the new value in the parent + table: that means the update fails */ upd_node_t* node, /* in: update node of the parent table */ - dict_foreign_t* foreign) /* in: foreign key constraint whose + dict_foreign_t* foreign, /* in: foreign key constraint whose type is != 0 */ + mem_heap_t* heap) /* in: memory heap to use as + temporary storage */ { upd_node_t* cascade = node->cascade_node; dict_table_t* table = foreign->foreign_table; @@ -381,14 +387,16 @@ row_ins_cascade_calc_update_vec( upd_field_t* parent_ufield; ulint n_fields_updated; ulint parent_field_no; + dtype_t* type; ulint i; ulint j; ut_a(node && foreign && cascade && table && index); /* Calculate the appropriate update vector which will set the fields - in the child index record to the same value as the referenced index - record will get in the update. */ + in the child index record to the same value (possibly padded with + spaces if the column is a fixed length CHAR or FIXBINARY column) as + the referenced index record will get in the update. */ parent_table = node->table; ut_a(parent_table == foreign->referenced_table); @@ -424,7 +432,56 @@ row_ins_cascade_calc_update_vec( dict_table_get_nth_col_pos(table, dict_index_get_nth_col_no(index, i)); ufield->exp = NULL; + ufield->new_val = parent_ufield->new_val; + + type = dict_index_get_nth_type(index, i); + + /* Do not allow a NOT NULL column to be + updated as NULL */ + + if (ufield->new_val.len == UNIV_SQL_NULL + && (type->prtype & DATA_NOT_NULL)) { + + return(ULINT_UNDEFINED); + } + + /* If the new value would not fit in the + column, do not allow the update */ + + if (ufield->new_val.len != UNIV_SQL_NULL + && ufield->new_val.len + > dtype_get_len(type)) { + + return(ULINT_UNDEFINED); + } + + /* If the parent column type has a different + length than the child column type, we may + need to pad with spaces the new value of the + child column */ + + if (dtype_is_fixed_size(type) + && ufield->new_val.len != UNIV_SQL_NULL + && ufield->new_val.len + < dtype_get_fixed_size(type)) { + + ufield->new_val.data = + mem_heap_alloc(heap, + dtype_get_fixed_size(type)); + ufield->new_val.len = + dtype_get_fixed_size(type); + ut_a(dtype_get_pad_char(type) + != ULINT_UNDEFINED); + + memset(ufield->new_val.data, + (byte)dtype_get_pad_char(type), + dtype_get_fixed_size(type)); + ut_memcpy(ufield->new_val.data, + parent_ufield->new_val.data, + parent_ufield->new_val.len); + } + ufield->extern_storage = FALSE; n_fields_updated++; @@ -570,9 +627,11 @@ row_ins_foreign_check_on_constraint( dict_index_t* clust_index; dtuple_t* ref; mem_heap_t* tmp_heap; + mem_heap_t* upd_vec_heap = NULL; rec_t* rec; rec_t* clust_rec; upd_t* update; + ulint n_to_update; ulint err; ulint i; char* ptr; @@ -597,8 +656,10 @@ row_ins_foreign_check_on_constraint( *ptr = '\0'; /* We call a function in ha_innodb.cc */ +#ifndef UNIV_HOTBACKUP innobase_invalidate_query_cache(thr_get_trx(thr), table_name_buf, ut_strlen(table->name) + 1); +#endif node = thr->run_node; if (node->is_delete && 0 == (foreign->type & @@ -828,7 +889,21 @@ row_ins_foreign_check_on_constraint( /* Build the appropriate update vector which sets changing foreign->n_fields first fields in rec to new values */ - row_ins_cascade_calc_update_vec(node, foreign); + upd_vec_heap = mem_heap_create(256); + + n_to_update = row_ins_cascade_calc_update_vec(node, foreign, + upd_vec_heap); + if (n_to_update == ULINT_UNDEFINED) { + err = DB_ROW_IS_REFERENCED; + + row_ins_foreign_report_err( +(char*)"Trying a cascaded update where the updated value in the child\n" +"table would not fit in the length of the column, or the value would\n" +"be NULL and the column is declared as not NULL in the child table,", + thr, foreign, btr_pcur_get_rec(pcur), entry); + + goto nonstandard_exit_func; + } if (cascade->update->n_fields == 0) { @@ -867,10 +942,18 @@ row_ins_foreign_check_on_constraint( btr_pcur_restore_position(BTR_SEARCH_LEAF, pcur, mtr); + if (upd_vec_heap) { + mem_heap_free(upd_vec_heap); + } + return(err); nonstandard_exit_func: + if (upd_vec_heap) { + mem_heap_free(upd_vec_heap); + } + btr_pcur_store_position(pcur, mtr); mtr_commit(mtr); @@ -1275,6 +1358,11 @@ row_ins_unique_report_err( dtuple_t* entry, /* in: index entry to insert in the index */ dict_index_t* index) /* in: index */ { + UT_NOT_USED(thr); + UT_NOT_USED(rec); + UT_NOT_USED(entry); + UT_NOT_USED(index); + #ifdef notdefined /* Disable reporting to test if the slowdown of REPLACE in 4.0.13 was caused by this! */ @@ -1816,7 +1904,7 @@ row_ins_index_entry( /* Try first optimistic descent to the B-tree */ err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry, - ext_vec, n_ext_vec, thr); + ext_vec, n_ext_vec, thr); if (err != DB_FAIL) { return(err); @@ -1832,13 +1920,15 @@ row_ins_index_entry( /*************************************************************** Sets the values of the dtuple fields in entry from the values of appropriate columns in row. */ -UNIV_INLINE +static void row_ins_index_entry_set_vals( /*=========================*/ + dict_index_t* index, /* in: index */ dtuple_t* entry, /* in: index entry to make */ dtuple_t* row) /* in: row */ { + dict_field_t* ind_field; dfield_t* field; dfield_t* row_field; ulint n_fields; @@ -1850,11 +1940,21 @@ row_ins_index_entry_set_vals( for (i = 0; i < n_fields; i++) { field = dtuple_get_nth_field(entry, i); + ind_field = dict_index_get_nth_field(index, i); - row_field = dtuple_get_nth_field(row, field->col_no); + row_field = dtuple_get_nth_field(row, ind_field->col->ind); + + /* Check column prefix indexes */ + if (ind_field->prefix_len > 0 + && dfield_get_len(row_field) != UNIV_SQL_NULL + && dfield_get_len(row_field) > ind_field->prefix_len) { + + field->len = ind_field->prefix_len; + } else { + field->len = row_field->len; + } field->data = row_field->data; - field->len = row_field->len; } } @@ -1873,7 +1973,7 @@ row_ins_index_entry_step( ut_ad(dtuple_check_typed(node->row)); - row_ins_index_entry_set_vals(node->entry, node->row); + row_ins_index_entry_set_vals(node->index, node->entry, node->row); ut_ad(dtuple_check_typed(node->entry)); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 428e4d568f3..61ba9111b91 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -76,9 +76,6 @@ row_mysql_store_blob_ref( also to set the NULL bit in the MySQL record header! */ { - ulint sum = 0; - ulint i; - /* MySQL might assume the field is set to zero except the length and the pointer fields */ @@ -93,22 +90,6 @@ row_mysql_store_blob_ref( ut_a(col_len - 8 > 2 || len < 256 * 256); ut_a(col_len - 8 > 3 || len < 256 * 256 * 256); - /* We try to track an elusive bug which probably was fixed - May 9, 2002, but better be sure: we probe the data buffer - to make sure it is in valid allocated memory */ - - for (i = 0; i < len; i++) { - - sum += (ulint)(data + i); - } - - /* The variable below is identically false, we just fool the - compiler to not optimize away our loop */ - if (row_mysql_identically_false) { - - printf("Sum %lu\n", sum); - } - mach_write_to_n_little_endian(dest, col_len - 8, len); ut_memcpy(dest + col_len - 8, (byte*)&data, sizeof(byte*)); @@ -952,7 +933,8 @@ row_update_for_mysql( if (prebuilt->pcur->btr_cur.index == clust_index) { btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur); } else { - btr_pcur_copy_stored_position(node->pcur, prebuilt->clust_pcur); + btr_pcur_copy_stored_position(node->pcur, + prebuilt->clust_pcur); } ut_a(node->pcur->rel_pos == BTR_PCUR_ON); @@ -1477,8 +1459,7 @@ row_create_index_for_mysql( ulint namelen; ulint keywordlen; ulint err; - ulint i; - ulint j; + ulint i, j; ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX)); ut_ad(mutex_own(&(dict_sys->mutex))); @@ -1486,23 +1467,9 @@ row_create_index_for_mysql( trx->op_info = (char *) "creating index"; - trx_start_if_not_started(trx); - - namelen = ut_strlen(index->table_name); - - keywordlen = ut_strlen("_recover_innodb_tmp_table"); - - if (namelen >= keywordlen - && 0 == ut_memcmp( - index->table_name + namelen - keywordlen, - (char*)"_recover_innodb_tmp_table", keywordlen)) { - - return(DB_SUCCESS); - } - /* Check that the same column does not appear twice in the index. - InnoDB assumes this in its algorithms, e.g., update of an index - entry */ + Starting from 4.0.14 InnoDB should be able to cope with that, but + safer not to allow them. */ for (i = 0; i < dict_index_get_n_fields(index); i++) { for (j = 0; j < i; j++) { @@ -1525,6 +1492,20 @@ row_create_index_for_mysql( } } + trx_start_if_not_started(trx); + + namelen = ut_strlen(index->table_name); + + keywordlen = ut_strlen("_recover_innodb_tmp_table"); + + if (namelen >= keywordlen + && 0 == ut_memcmp( + index->table_name + namelen - keywordlen, + (char*)"_recover_innodb_tmp_table", keywordlen)) { + + return(DB_SUCCESS); + } + heap = mem_heap_create(512); trx->dict_operation = TRUE; @@ -1542,6 +1523,7 @@ row_create_index_for_mysql( que_graph_free((que_t*) que_node_get_parent(thr)); error_handling: + if (err != DB_SUCCESS) { /* We have special error handling here */ @@ -2541,7 +2523,7 @@ loop: prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); - ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, ROW_SEL_NEXT); + ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, ROW_SEL_NEXT); goto loop; } diff --git a/innobase/row/row0row.c b/innobase/row/row0row.c index 40a775143f4..6c0c6c04cd5 100644 --- a/innobase/row/row0row.c +++ b/innobase/row/row0row.c @@ -136,7 +136,14 @@ row_build_index_entry( dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col)); dfield_copy(dfield, dfield2); - dfield->col_no = dict_col_get_no(col); + + /* If a column prefix index, take only the prefix */ + if (ind_field->prefix_len > 0 + && dfield_get_len(dfield2) != UNIV_SQL_NULL + && dfield_get_len(dfield2) > ind_field->prefix_len) { + + dfield_set_len(dfield, ind_field->prefix_len); + } } ut_ad(dtuple_check_typed(entry)); @@ -146,8 +153,7 @@ row_build_index_entry( /*********************************************************************** An inverse function to dict_row_build_index_entry. Builds a row from a -record in a clustered index. NOTE that externally stored (often big) -fields are always copied to heap. */ +record in a clustered index. */ dtuple_t* row_build( @@ -172,6 +178,7 @@ row_build( { dtuple_t* row; dict_table_t* table; + dict_field_t* ind_field; dict_col_t* col; dfield_t* dfield; ulint n_fields; @@ -204,19 +211,24 @@ row_build( dict_table_copy_types(row, table); for (i = 0; i < n_fields; i++) { + ind_field = dict_index_get_nth_field(index, i); - col = dict_field_get_col(dict_index_get_nth_field(index, i)); - dfield = dtuple_get_nth_field(row, dict_col_get_no(col)); - field = rec_get_nth_field(rec, i, &len); + if (ind_field->prefix_len == 0) { - if (type == ROW_COPY_ALSO_EXTERNALS - && rec_get_nth_field_extern_bit(rec, i)) { + col = dict_field_get_col(ind_field); + dfield = dtuple_get_nth_field(row, + dict_col_get_no(col)); + field = rec_get_nth_field(rec, i, &len); - field = btr_rec_copy_externally_stored_field(rec, - i, &len, heap); + if (type == ROW_COPY_ALSO_EXTERNALS + && rec_get_nth_field_extern_bit(rec, i)) { + + field = btr_rec_copy_externally_stored_field( + rec, i, &len, heap); + } + + dfield_set_data(dfield, field, len); } - - dfield_set_data(dfield, field, len); } ut_ad(dtuple_check_typed(row)); @@ -371,7 +383,6 @@ row_build_row_ref( dict_table_t* table; dict_index_t* clust_index; dfield_t* dfield; - dict_col_t* col; dtuple_t* ref; byte* field; ulint len; @@ -403,24 +414,13 @@ row_build_row_ref( for (i = 0; i < ref_len; i++) { dfield = dtuple_get_nth_field(ref, i); - col = dict_field_get_col( - dict_index_get_nth_field(clust_index, i)); - pos = dict_index_get_nth_col_pos(index, dict_col_get_no(col)); + pos = dict_index_get_nth_field_pos(index, clust_index, i); - if (pos != ULINT_UNDEFINED) { - field = rec_get_nth_field(rec, pos, &len); + ut_a(pos != ULINT_UNDEFINED); + + field = rec_get_nth_field(rec, pos, &len); - dfield_set_data(dfield, field, len); - } else { - ut_ad(table->type == DICT_TABLE_CLUSTER_MEMBER); - ut_ad(i == table->mix_len); - - dfield_set_data(dfield, - mem_heap_alloc(heap, table->mix_id_len), - table->mix_id_len); - ut_memcpy(dfield_get_data(dfield), table->mix_id_buf, - table->mix_id_len); - } + dfield_set_data(dfield, field, len); } ut_ad(dtuple_check_typed(ref)); @@ -448,7 +448,6 @@ row_build_row_ref_in_tuple( dict_table_t* table; dict_index_t* clust_index; dfield_t* dfield; - dict_col_t* col; byte* field; ulint len; ulint ref_len; @@ -483,19 +482,13 @@ row_build_row_ref_in_tuple( for (i = 0; i < ref_len; i++) { dfield = dtuple_get_nth_field(ref, i); - col = dict_field_get_col( - dict_index_get_nth_field(clust_index, i)); - pos = dict_index_get_nth_col_pos(index, dict_col_get_no(col)); + pos = dict_index_get_nth_field_pos(index, clust_index, i); - if (pos != ULINT_UNDEFINED) { - field = rec_get_nth_field(rec, pos, &len); + ut_a(pos != ULINT_UNDEFINED); + + field = rec_get_nth_field(rec, pos, &len); - dfield_set_data(dfield, field, len); - } else { - ut_ad(table->type == DICT_TABLE_CLUSTER_MEMBER); - ut_ad(i == table->mix_len); - ut_a(0); - } + dfield_set_data(dfield, field, len); } ut_ad(dtuple_check_typed(ref)); @@ -517,6 +510,7 @@ row_build_row_ref_from_row( directly into data of this row */ { dict_index_t* clust_index; + dict_field_t* field; dfield_t* dfield; dfield_t* dfield2; dict_col_t* col; @@ -533,13 +527,21 @@ row_build_row_ref_from_row( for (i = 0; i < ref_len; i++) { dfield = dtuple_get_nth_field(ref, i); - - col = dict_field_get_col( - dict_index_get_nth_field(clust_index, i)); - + + field = dict_index_get_nth_field(clust_index, i); + + col = dict_field_get_col(field); + dfield2 = dtuple_get_nth_field(row, dict_col_get_no(col)); dfield_copy(dfield, dfield2); + + if (field->prefix_len > 0 + && dfield->len != UNIV_SQL_NULL + && dfield->len > field->prefix_len) { + + dfield->len = field->prefix_len; + } } ut_ad(dtuple_check_typed(ref)); diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 4732472d805..114ebf870b0 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -65,41 +65,50 @@ row_sel_sec_rec_is_for_clust_rec( rec_t* sec_rec, /* in: secondary index record */ dict_index_t* sec_index, /* in: secondary index */ rec_t* clust_rec, /* in: clustered index record */ - dict_index_t* clust_index __attribute__((unused))) - /* in: clustered index */ + dict_index_t* clust_index) /* in: clustered index */ { - dict_col_t* col; - byte* sec_field; - ulint sec_len; - byte* clust_field; - ulint clust_len; - ulint n; - ulint i; + dict_field_t* ifield; + dict_col_t* col; + byte* sec_field; + ulint sec_len; + byte* clust_field; + ulint clust_len; + ulint n; + ulint i; - n = dict_index_get_n_ordering_defined_by_user(sec_index); + UT_NOT_USED(clust_index); - for (i = 0; i < n; i++) { - col = dict_field_get_col( - dict_index_get_nth_field(sec_index, i)); + n = dict_index_get_n_ordering_defined_by_user(sec_index); - clust_field = rec_get_nth_field(clust_rec, - dict_col_get_clust_pos(col), - &clust_len); - sec_field = rec_get_nth_field(sec_rec, i, &sec_len); + for (i = 0; i < n; i++) { + ifield = dict_index_get_nth_field(sec_index, i); + col = dict_field_get_col(ifield); + + clust_field = rec_get_nth_field(clust_rec, + dict_col_get_clust_pos(col), + &clust_len); + sec_field = rec_get_nth_field(sec_rec, i, &sec_len); - if (sec_len != clust_len) { + if (ifield->prefix_len > 0 + && clust_len != UNIV_SQL_NULL + && clust_len > ifield->prefix_len) { - return(FALSE); + clust_len = ifield->prefix_len; } - if (0 != cmp_data_data(dict_col_get_type(col), - clust_field, clust_len, - sec_field, sec_len)) { - return(FALSE); - } - } + if (sec_len != clust_len) { - return(TRUE); + return(FALSE); + } + + if (0 != cmp_data_data(dict_col_get_type(col), + clust_field, clust_len, + sec_field, sec_len)) { + return(FALSE); + } + } + + return(TRUE); } /************************************************************************* @@ -606,7 +615,7 @@ row_sel_get_clust_rec( /* Try to place a lock on the index record */ err = lock_clust_rec_read_check_and_lock(0, clust_rec, index, - node->row_lock_mode, LOCK_ORDINARY, thr); + node->row_lock_mode, LOCK_ORDINARY, thr); if (err != DB_SUCCESS) { return(err); @@ -656,7 +665,7 @@ row_sel_get_clust_rec( *out_rec = clust_rec; return(DB_SUCCESS); - } + } } /* Fetch the columns needed in test conditions */ @@ -1850,9 +1859,11 @@ row_printf_step( } /******************************************************************** -Converts a key value stored in MySQL format to an Innobase dtuple. -The last field of the key value may be just a prefix of a fixed length -field: hence the parameter key_len. */ +Converts a key value stored in MySQL format to an Innobase dtuple. The last +field of the key value may be just a prefix of a fixed length field: hence +the parameter key_len. But currently we do not allow search keys where the +last field is only a prefix of the full key field len and print a warning if +such appears. */ void row_sel_convert_mysql_key_to_innobase( @@ -1863,17 +1874,24 @@ row_sel_convert_mysql_key_to_innobase( to index! */ byte* buf, /* in: buffer to use in field conversions */ + ulint buf_len, /* in: buffer length */ dict_index_t* index, /* in: index of the key value */ byte* key_ptr, /* in: MySQL key value */ ulint key_len) /* in: MySQL key value length */ { + byte* original_buf = buf; + dict_field_t* field; dfield_t* dfield; - ulint offset; - ulint len; + ulint data_offset; + ulint data_len; + ulint data_field_len; + ibool is_null; byte* key_end; ulint n_fields = 0; + ulint type; - UT_NOT_USED(index); + /* For documentation of the key value storage format in MySQL, see + ha_innobase::store_key_val_for_row() in ha_innodb.cc. */ key_end = key_ptr + key_len; @@ -1882,11 +1900,14 @@ row_sel_convert_mysql_key_to_innobase( dtuple_set_n_fields(tuple, ULINT_MAX); dfield = dtuple_get_nth_field(tuple, 0); + field = dict_index_get_nth_field(index, 0); if (dfield_get_type(dfield)->mtype == DATA_SYS) { - /* A special case: we are looking for a position in a - generated clustered index: the first and the only - ordering column is ROW_ID */ + /* A special case: we are looking for a position in the + generated clustered index which InnoDB automatically added + to a table with no primary key: the first and the only + ordering column is ROW_ID which InnoDB stored to the key_ptr + buffer. */ ut_a(key_len == DATA_ROW_ID_LEN); @@ -1897,70 +1918,114 @@ row_sel_convert_mysql_key_to_innobase( return; } - while (key_ptr < key_end) { - offset = 0; - len = dfield_get_type(dfield)->len; + while (key_ptr < key_end) { - n_fields++; + ut_a(dict_col_get_type(field->col)->mtype + == dfield_get_type(dfield)->mtype); + + data_offset = 0; + is_null = FALSE; if (!(dfield_get_type(dfield)->prtype & DATA_NOT_NULL)) { /* The first byte in the field tells if this is an SQL NULL value */ - offset = 1; + data_offset = 1; - if (*key_ptr != 0) { + if (*key_ptr != 0) { dfield_set_data(dfield, NULL, UNIV_SQL_NULL); - goto next_part; + is_null = TRUE; } } - row_mysql_store_col_in_innobase_format( - dfield, buf, key_ptr + offset, len, - dfield_get_type(dfield)->mtype, + type = dfield_get_type(dfield)->mtype; + + /* Calculate data length and data field total length */ + + if (type == DATA_BLOB) { + /* The key field is a column prefix of a BLOB or + TEXT type column */ + + ut_a(field->prefix_len > 0); + + /* MySQL stores the actual data length to the first 2 + bytes after the optional SQL NULL marker byte. The + storage format is little-endian. */ + + /* There are no key fields > 255 bytes currently in + MySQL */ + if (key_ptr[data_offset + 1] != 0) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: BLOB or TEXT prefix > 255 bytes in query to table %s\n", + index->table_name); + } + + data_len = key_ptr[data_offset]; + data_field_len = data_offset + 2 + field->prefix_len; + data_offset += 2; + + type = DATA_CHAR; /* now that we know the length, we + store the column value like it would + be a fixed char field */ + } else if (field->prefix_len > 0) { + data_len = field->prefix_len; + data_field_len = data_offset + data_len; + } else { + data_len = dfield_get_type(dfield)->len; + data_field_len = data_offset + data_len; + } + + /* Storing may use at most data_len bytes of buf */ + + if (!is_null) { + row_mysql_store_col_in_innobase_format( + dfield, buf, key_ptr + data_offset, + data_len, type, dfield_get_type(dfield)->prtype & DATA_UNSIGNED); - next_part: - key_ptr += (offset + len); + buf += data_len; + } + + key_ptr += data_field_len; if (key_ptr > key_end) { - /* The last field in key was not a complete - field but a prefix of it. + /* The last field in key was not a complete key field + but a prefix of it. - Print a warning about this! HA_READ_PREFIX_LAST - does not currently work in InnoDB with partial-field - key value prefixes. Since MySQL currently uses a - padding trick to calculate LIKE 'abc%' type queries - there should never be partial-field prefixes - in searches. */ + Print a warning about this! HA_READ_PREFIX_LAST does + not currently work in InnoDB with partial-field key + value prefixes. Since MySQL currently uses a padding + trick to calculate LIKE 'abc%' type queries there + should never be partial-field prefixes in searches. */ ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Warning: using a partial-field key prefix in search\n"); - ut_ad(dfield_get_len(dfield) != UNIV_SQL_NULL); - - dfield_set_data(dfield, buf, - len - (ulint)(key_ptr - key_end)); + if (!is_null) { + dfield->len -= (ulint)(key_ptr - key_end); + } } - buf += len; - + n_fields++; + field++; dfield++; } - /* We set the length of tuple to n_fields: we assume that - the memory area allocated for it is big enough (usually - bigger than n_fields). */ + ut_a(buf <= original_buf + buf_len); + + /* We set the length of tuple to n_fields: we assume that the memory + area allocated for it is big enough (usually bigger than n_fields). */ dtuple_set_n_fields(tuple, n_fields); } /****************************************************************** Stores the row id to the prebuilt struct. */ -UNIV_INLINE +static void row_sel_store_row_id_to_prebuilt( /*=============================*/ @@ -1970,11 +2035,22 @@ row_sel_store_row_id_to_prebuilt( { byte* data; ulint len; + char err_buf[1000]; data = rec_get_nth_field(index_rec, dict_index_get_sys_col_pos(index, DATA_ROW_ID), &len); - ut_a(len == DATA_ROW_ID_LEN); + if (len != DATA_ROW_ID_LEN) { + rec_sprintf(err_buf, 900, index_rec); + + fprintf(stderr, +"InnoDB: Error: Row id field is wrong length %lu in table %s index %s\n" +"InnoDB: Field number %lu, record:\n%s\n", + len, index->table_name, index->name, + dict_index_get_sys_col_pos(index, DATA_ROW_ID), + err_buf); + ut_a(0); + } ut_memcpy(prebuilt->row_id, data, len); } @@ -3021,7 +3097,7 @@ rec_loop: if (prebuilt->select_lock_type != LOCK_NONE && set_also_gap_locks) { - /* Try to place a lock on the index record */ + /* Try to place a lock on the index record */ err = sel_set_rec_lock(rec, index, prebuilt->select_lock_type, diff --git a/innobase/row/row0umod.c b/innobase/row/row0umod.c index b84e55ca643..b22e494f891 100644 --- a/innobase/row/row0umod.c +++ b/innobase/row/row0umod.c @@ -428,7 +428,8 @@ row_undo_mod_del_unmark_sec( found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur, &mtr); if (!found) { - fprintf(stderr, "InnoDB: error in sec index entry del undo in\n" + fprintf(stderr, + "InnoDB: error in sec index entry del undo in\n" "InnoDB: index %s table %s\n", index->name, index->table->name); dtuple_sprintf(err_buf, 900, entry); @@ -570,7 +571,7 @@ row_undo_mod_upd_exist_sec( the row */ row_upd_index_replace_new_col_vals(entry, index, - node->update); + node->update, NULL); row_undo_mod_del_unmark_sec(node, thr, index, entry); } diff --git a/innobase/row/row0upd.c b/innobase/row/row0upd.c index 5fce1c1861b..db68479509d 100644 --- a/innobase/row/row0upd.c +++ b/innobase/row/row0upd.c @@ -72,8 +72,9 @@ searched delete is obviously to keep the x-latch for several steps of query graph execution. */ /*************************************************************** -Checks if an update vector changes some of the first fields of an index -record. */ +Checks if an update vector changes some of the first ordering fields of an +index record. This is only used in foreign key checks and we can assume +that index does not contain column prefixes. */ static ibool row_upd_changes_first_fields( @@ -234,7 +235,8 @@ row_upd_check_references_constraints( if (err != DB_SUCCESS) { if (got_s_lock) { - row_mysql_unfreeze_data_dictionary(trx); + row_mysql_unfreeze_data_dictionary( + trx); } mem_heap_free(heap); @@ -350,14 +352,15 @@ row_upd_index_entry_sys_field( } /*************************************************************** -Returns TRUE if row update changes size of some field in index -or if some field to be updated is stored externally in rec or update. */ +Returns TRUE if row update changes size of some field in index or if some +field to be updated is stored externally in rec or update. */ ibool -row_upd_changes_field_size( -/*=======================*/ +row_upd_changes_field_size_or_external( +/*===================================*/ /* out: TRUE if the update changes the size of - some field in index */ + some field in index or the field is external + in rec or update */ rec_t* rec, /* in: record in clustered index */ dict_index_t* index, /* in: clustered index */ upd_t* update) /* in: update vector */ @@ -820,72 +823,58 @@ void row_upd_index_replace_new_col_vals( /*===============================*/ dtuple_t* entry, /* in/out: index entry where replaced */ - dict_index_t* index, /* in: index; NOTE that may also be a + dict_index_t* index, /* in: index; NOTE that this may also be a non-clustered index */ - upd_t* update) /* in: update vector */ + upd_t* update, /* in: update vector */ + mem_heap_t* heap) /* in: memory heap to which we allocate and + copy the new values, set this as NULL if you + do not want allocation */ { + dict_field_t* field; upd_field_t* upd_field; dfield_t* dfield; dfield_t* new_val; - ulint field_no; - dict_index_t* clust_index; + ulint j; ulint i; ut_ad(index); - clust_index = dict_table_get_first_index(index->table); - dtuple_set_info_bits(entry, update->info_bits); - for (i = 0; i < upd_get_n_fields(update); i++) { + for (j = 0; j < dict_index_get_n_fields(index); j++) { - upd_field = upd_get_nth_field(update, i); + field = dict_index_get_nth_field(index, j); - field_no = dict_index_get_nth_col_pos(index, - dict_index_get_nth_col_no(clust_index, - upd_field->field_no)); - if (field_no != ULINT_UNDEFINED) { - dfield = dtuple_get_nth_field(entry, field_no); + for (i = 0; i < upd_get_n_fields(update); i++) { - new_val = &(upd_field->new_val); + upd_field = upd_get_nth_field(update, i); - dfield_set_data(dfield, new_val->data, new_val->len); + if (upd_field->field_no == field->col->clust_pos) { + + dfield = dtuple_get_nth_field(entry, j); + + new_val = &(upd_field->new_val); + + dfield_set_data(dfield, new_val->data, + new_val->len); + if (heap && new_val->len != UNIV_SQL_NULL) { + dfield->data = mem_heap_alloc(heap, + new_val->len); + ut_memcpy(dfield->data, new_val->data, + new_val->len); + } + + if (field->prefix_len > 0 + && new_val->len != UNIV_SQL_NULL + && new_val->len > field->prefix_len) { + + dfield->len = field->prefix_len; + } + } } } } -/*************************************************************** -Replaces the new column values stored in the update vector to the -clustered index entry given. */ - -void -row_upd_clust_index_replace_new_col_vals( -/*=====================================*/ - dtuple_t* entry, /* in/out: index entry where replaced */ - upd_t* update) /* in: update vector */ -{ - upd_field_t* upd_field; - dfield_t* dfield; - dfield_t* new_val; - ulint field_no; - ulint i; - - dtuple_set_info_bits(entry, update->info_bits); - - for (i = 0; i < upd_get_n_fields(update); i++) { - - upd_field = upd_get_nth_field(update, i); - - field_no = upd_field->field_no; - - dfield = dtuple_get_nth_field(entry, field_no); - - new_val = &(upd_field->new_val); - - dfield_set_data(dfield, new_val->data, new_val->len); - } -} - /*************************************************************** Checks if an update vector changes an ordering field of an index record. This function is fast if the update vector is short or the number of ordering @@ -931,9 +920,15 @@ row_upd_changes_ord_field_binary( upd_field = upd_get_nth_field(update, j); + /* Note that if the index field is a column prefix + then it may be that row does not contain an externally + stored part of the column value, and we cannot compare + the datas */ + if (col_pos == upd_field->field_no - && (row == NULL - || !dfield_datas_are_binary_equal( + && (row == NULL + || ind_field->prefix_len > 0 + || !dfield_datas_are_binary_equal( dtuple_get_nth_field(row, col_no), &(upd_field->new_val)))) { return(TRUE); @@ -978,8 +973,9 @@ row_upd_changes_some_index_ord_field_binary( } /*************************************************************** -Checks if an update vector changes some of the first fields of an index -record. */ +Checks if an update vector changes some of the first ordering fields of an +index record. This is only used in foreign key checks and we can assume +that index does not contain column prefixes. */ static ibool row_upd_changes_first_fields( @@ -1013,9 +1009,10 @@ row_upd_changes_first_fields( upd_field = upd_get_nth_field(update, j); if (col_pos == upd_field->field_no - && cmp_dfield_dfield( + && (ind_field->prefix_len > 0 + || 0 != cmp_dfield_dfield( dtuple_get_nth_field(entry, i), - &(upd_field->new_val))) { + &(upd_field->new_val)))) { return(TRUE); } } @@ -1204,7 +1201,7 @@ close_cur: } /* Build a new index entry */ - row_upd_index_replace_new_col_vals(entry, index, node->update); + row_upd_index_replace_new_col_vals(entry, index, node->update, NULL); /* Insert new index entry */ err = row_ins_index_entry(index, entry, NULL, 0, thr); @@ -1317,12 +1314,12 @@ row_upd_clust_rec_by_insert( entry = row_build_index_entry(node->row, index, heap); - row_upd_clust_index_replace_new_col_vals(entry, node->update); + row_upd_index_replace_new_col_vals(entry, index, node->update, NULL); row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id); /* If we return from a lock wait, for example, we may have - extern fields marked as not-owned in entry (marked if the + extern fields marked as not-owned in entry (marked in the if-branch above). We must unmark them. */ btr_cur_unmark_dtuple_extern_fields(entry, node->ext_vec, @@ -1702,9 +1699,9 @@ function_exit: /* Do some cleanup */ if (node->row != NULL) { - mem_heap_empty(node->heap); node->row = NULL; node->n_ext_vec = 0; + mem_heap_empty(node->heap); } node->state = UPD_NODE_UPDATE_CLUSTERED; diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c index cd8b18e5e12..91aaba40812 100644 --- a/innobase/row/row0vers.c +++ b/innobase/row/row0vers.c @@ -27,6 +27,7 @@ Created 2/6/1997 Heikki Tuuri #include "row0upd.h" #include "rem0cmp.h" #include "read0read.h" +#include "lock0lock.h" /********************************************************************* Finds out if an active transaction has inserted or modified a secondary @@ -111,6 +112,14 @@ row_vers_impl_x_locked_off_kernel( return(NULL); } + if (!lock_check_trx_id_sanity(trx_id, clust_rec, clust_index, TRUE)) { + /* Corruption noticed: try to avoid a crash by returning */ + + mtr_commit(&mtr); + + return(NULL); + } + /* We look up if some earlier version of the clustered index record would require rec to be in a different state (delete marked or unmarked, or not existing). If there is such a version, then rec was @@ -177,7 +186,8 @@ row_vers_impl_x_locked_off_kernel( /* If we get here, we know that the trx_id transaction is still active and it has modified prev_version. Let us check - if prev_version would require rec to be in a different state. */ + if prev_version would require rec to be in a different + state. */ vers_del = rec_get_deleted_flag(prev_version); diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 2a93ca966eb..d13d499dd17 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -286,6 +286,7 @@ ulint srv_test_n_mutexes = ULINT_MAX; i/o handler thread */ char* srv_io_thread_op_info[SRV_MAX_N_IO_THREADS]; +char* srv_io_thread_function[SRV_MAX_N_IO_THREADS]; time_t srv_last_monitor_time; @@ -2399,8 +2400,9 @@ srv_sprintf_innodb_monitor( srv_conc_n_threads, srv_conc_n_waiting_threads); #ifdef UNIV_LINUX buf += sprintf(buf, - "Main thread process no %lu, state: %s\n", + "Main thread process no. %lu, id %lu, state: %s\n", srv_main_thread_process_no, + srv_main_thread_id, srv_main_thread_op_info); #else buf += sprintf(buf, @@ -2464,8 +2466,8 @@ srv_lock_timeout_and_monitor_thread( ulint i; #ifdef UNIV_DEBUG_THREAD_CREATION - printf("Lock timeout thread starts\n"); - printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id())); + printf("Lock timeout thread starts, id %lu\n", + os_thread_pf(os_thread_get_curr_id())); #endif UT_NOT_USED(arg); srv_last_monitor_time = time(NULL); @@ -2637,8 +2639,8 @@ srv_error_monitor_thread( UT_NOT_USED(arg); #ifdef UNIV_DEBUG_THREAD_CREATION - printf("Error monitor thread starts\n"); - printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id())); + printf("Error monitor thread starts, id %lu\n", + os_thread_pf(os_thread_get_curr_id())); #endif loop: srv_error_monitor_active = TRUE; @@ -2760,8 +2762,8 @@ srv_master_thread( UT_NOT_USED(arg); #ifdef UNIV_DEBUG_THREAD_CREATION - printf("Master thread starts\n"); - printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id())); + printf("Master thread starts, id %lu\n", + os_thread_pf(os_thread_get_curr_id())); #endif srv_main_thread_process_no = os_proc_get_number(); srv_main_thread_id = os_thread_pf(os_thread_get_curr_id()); diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 1f278d82bc0..964e728b23c 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -415,8 +415,8 @@ io_handler_thread( segment = *((ulint*)arg); #ifdef UNIV_DEBUG_THREAD_CREATION - printf("Io handler thread %lu starts\n", segment); - printf("Thread id %lu\n", os_thread_pf(os_thread_get_curr_id())); + printf("Io handler thread %lu starts, id %lu\n", segment, + os_thread_pf(os_thread_get_curr_id())); #endif for (i = 0;; i++) { fil_aio_wait(segment); @@ -1492,7 +1492,9 @@ innobase_shutdown_for_mysql(void) } /* 1. Flush buffer pool to disk, write the current lsn to - the tablespace header(s), and copy all log data to archive */ + the tablespace header(s), and copy all log data to archive. + The step 1 is the real InnoDB shutdown. The remaining steps + just free data structures after the shutdown. */ logs_empty_and_mark_files_at_shutdown(); diff --git a/innobase/trx/trx0rec.c b/innobase/trx/trx0rec.c index 05e179e06a5..9453189d598 100644 --- a/innobase/trx/trx0rec.c +++ b/innobase/trx/trx0rec.c @@ -272,8 +272,8 @@ trx_undo_page_report_insert( mach_write_to_2(undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE, ptr - undo_page); - /* Write the log entry to the REDO log of this change in the UNDO log */ - + /* Write the log entry to the REDO log of this change in the UNDO + log */ trx_undof_page_add_undo_rec_log(undo_page, first_free, ptr - undo_page, mtr); return(first_free); @@ -492,7 +492,8 @@ trx_undo_page_report_modify( /* Reserve 2 bytes for the pointer to the next undo log record */ ptr += 2; - /* Store first some general parameters to the undo log */ + /* Store first some general parameters to the undo log */ + if (update) { if (rec_get_deleted_flag(rec)) { type_cmpl = TRX_UNDO_UPD_DEL_REC; @@ -526,8 +527,7 @@ trx_undo_page_report_modify( /* Store the values of the system columns */ trx_id = dict_index_rec_get_sys_col(index, DATA_TRX_ID, rec); - roll_ptr = dict_index_rec_get_sys_col(index, DATA_ROLL_PTR, rec); - + roll_ptr = dict_index_rec_get_sys_col(index, DATA_ROLL_PTR, rec); len = mach_dulint_write_compressed(ptr, trx_id); ptr += len; @@ -632,7 +632,11 @@ trx_undo_page_report_modify( columns which occur as ordering fields in any index. This info is used in the purge of old versions where we use it to build and search the delete marked index records, to look if we can remove them from the - index tree. */ + index tree. Note that starting from 4.0.14 also externally stored + fields can be ordering in some index. But we always store at least + 384 first bytes locally to the clustered index record, which means + we can construct the column prefix fields in the index from the + stored data. */ if (!update || !(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { @@ -1408,11 +1412,11 @@ trx_undo_prev_version_build( return(DB_ERROR); } - if (row_upd_changes_field_size(rec, index, update)) { + if (row_upd_changes_field_size_or_external(rec, index, update)) { - entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap); - - row_upd_clust_index_replace_new_col_vals(entry, update); + entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, + heap); + row_upd_index_replace_new_col_vals(entry, index, update, heap); buf = mem_heap_alloc(heap, rec_get_converted_size(entry)); diff --git a/innobase/trx/trx0roll.c b/innobase/trx/trx0roll.c index a9f8c5ad22c..7d1b341221c 100644 --- a/innobase/trx/trx0roll.c +++ b/innobase/trx/trx0roll.c @@ -52,6 +52,11 @@ trx_general_rollback_for_mysql( que_thr_t* thr; roll_node_t* roll_node; + /* Tell Innobase server that there might be work for + utility threads: */ + + srv_active_wake_master_thread(); + trx_start_if_not_started(trx); heap = mem_heap_create(512); @@ -89,6 +94,11 @@ trx_general_rollback_for_mysql( ut_a(trx->error_state == DB_SUCCESS); + /* Tell Innobase server that there might be work for + utility threads: */ + + srv_active_wake_master_thread(); + return((int) trx->error_state); } @@ -110,20 +120,8 @@ trx_rollback_for_mysql( trx->op_info = (char *) "rollback"; - /* Tell Innobase server that there might be work for - utility threads: */ - - srv_active_wake_master_thread(); - err = trx_general_rollback_for_mysql(trx, FALSE, NULL); - trx_mark_sql_stat_end(trx); - - /* Tell Innobase server that there might be work for - utility threads: */ - - srv_active_wake_master_thread(); - trx->op_info = (char *) ""; return(err); @@ -147,25 +145,191 @@ trx_rollback_last_sql_stat_for_mysql( trx->op_info = (char *) "rollback of SQL statement"; - /* Tell Innobase server that there might be work for - utility threads: */ - - srv_active_wake_master_thread(); - err = trx_general_rollback_for_mysql(trx, TRUE, &(trx->last_sql_stat_start)); + /* The following call should not be needed, but we play safe: */ trx_mark_sql_stat_end(trx); - /* Tell Innobase server that there might be work for - utility threads: */ - - srv_active_wake_master_thread(); - trx->op_info = (char *) ""; return(err); } +/*********************************************************************** +Frees savepoint structs. */ + +void +trx_roll_savepoints_free( +/*=====================*/ + trx_t* trx, /* in: transaction handle */ + trx_named_savept_t* savep) /* in: free all savepoints > this one; + if this is NULL, free all savepoints + of trx */ +{ + trx_named_savept_t* next_savep; + + if (savep == NULL) { + savep = UT_LIST_GET_FIRST(trx->trx_savepoints); + } else { + savep = UT_LIST_GET_NEXT(trx_savepoints, savep); + } + + while (savep != NULL) { + next_savep = UT_LIST_GET_NEXT(trx_savepoints, savep); + + UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep); + mem_free(savep->name); + mem_free(savep); + + savep = next_savep; + } +} + +/*********************************************************************** +Rolls back a transaction back to a named savepoint. Modifications after the +savepoint are undone but InnoDB does NOT release the corresponding locks +which are stored in memory. If a lock is 'implicit', that is, a new inserted +row holds a lock where the lock information is carried by the trx id stored in +the row, these locks are naturally released in the rollback. Savepoints which +were set after this savepoint are deleted. */ + +ulint +trx_rollback_to_savepoint_for_mysql( +/*================================*/ + /* out: if no savepoint + of the name found then + DB_NO_SAVEPOINT, + otherwise DB_SUCCESS */ + trx_t* trx, /* in: transaction handle */ + 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 + information to remove the + binlog entries of the queries + executed after the savepoint */ +{ + trx_named_savept_t* savep; + ulint err; + + savep = UT_LIST_GET_FIRST(trx->trx_savepoints); + + while (savep != NULL) { + if (0 == ut_strcmp(savep->name, savepoint_name)) { + /* Found */ + break; + } + savep = UT_LIST_GET_NEXT(trx_savepoints, savep); + } + + if (savep == NULL) { + + return(DB_NO_SAVEPOINT); + } + + if (trx->conc_state == TRX_NOT_STARTED) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: transaction has a savepoint %s though it is not started\n", + savep->name); + return(DB_ERROR); + } + + /* We can now free all savepoints strictly later than this one */ + + trx_roll_savepoints_free(trx, savep); + + *mysql_binlog_cache_pos = savep->mysql_binlog_cache_pos; + + trx->op_info = (char *) "rollback to a savepoint"; + + err = trx_general_rollback_for_mysql(trx, TRUE, &(savep->savept)); + + /* Store the current undo_no of the transaction so that we know where + to roll back if we have to roll back the next SQL statement: */ + + trx_mark_sql_stat_end(trx); + + trx->op_info = (char *) ""; + + return(err); +} + +/*********************************************************************** +Creates a named savepoint. If the transaction is not yet started, starts it. +If there is already a savepoint of the same name, this call erases that old +savepoint and replaces it with a new. Savepoints are deleted in a transaction +commit or rollback. */ + +ulint +trx_savepoint_for_mysql( +/*====================*/ + /* out: always DB_SUCCESS */ + trx_t* trx, /* in: transaction handle */ + 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 + savepoint */ +{ + trx_named_savept_t* savep; + + ut_a(trx); + ut_a(savepoint_name); + + trx_start_if_not_started(trx); + + savep = UT_LIST_GET_FIRST(trx->trx_savepoints); + + while (savep != NULL) { + if (0 == ut_strcmp(savep->name, savepoint_name)) { + /* Found */ + break; + } + savep = UT_LIST_GET_NEXT(trx_savepoints, savep); + } + + if (savep) { + /* There is a savepoint with the same name: free that */ + + UT_LIST_REMOVE(trx_savepoints, trx->trx_savepoints, savep); + + mem_free(savep->name); + mem_free(savep); + } + + /* Create a new savepoint and add it as the last in the list */ + + savep = mem_alloc(sizeof(trx_named_savept_t)); + + savep->name = mem_alloc(1 + ut_strlen(savepoint_name)); + ut_memcpy(savep->name, savepoint_name, 1 + ut_strlen(savepoint_name)); + + savep->savept = trx_savept_take(trx); + + savep->mysql_binlog_cache_pos = binlog_cache_pos; + + UT_LIST_ADD_LAST(trx_savepoints, trx->trx_savepoints, savep); + + return(DB_SUCCESS); +} + +/*********************************************************************** +Returns a transaction savepoint taken at this point in time. */ + +trx_savept_t +trx_savept_take( +/*============*/ + /* out: savepoint */ + trx_t* trx) /* in: transaction */ +{ + trx_savept_t savept; + + savept.least_undo_no = trx->undo_no; + + return(savept); +} + /*********************************************************************** Rollback or clean up transactions which have no user session. If the transaction already was committed, then we clean up a possible insert @@ -325,22 +489,6 @@ loop: goto loop; } - -/*********************************************************************** -Returns a transaction savepoint taken at this point in time. */ - -trx_savept_t -trx_savept_take( -/*============*/ - /* out: savepoint */ - trx_t* trx) /* in: transaction */ -{ - trx_savept_t savept; - - savept.least_undo_no = trx->undo_no; - - return(savept); -} /*********************************************************************** Creates an undo number array. */ diff --git a/innobase/trx/trx0sys.c b/innobase/trx/trx0sys.c index 51aad60d3e2..f1b03fff3bd 100644 --- a/innobase/trx/trx0sys.c +++ b/innobase/trx/trx0sys.c @@ -321,8 +321,8 @@ trx_sys_doublewrite_restore_corrupt_pages(void) for (i = 0; i < TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * 2; i++) { - space_id = mach_read_from_4(page + FIL_PAGE_SPACE); page_no = mach_read_from_4(page + FIL_PAGE_OFFSET); + space_id = 0; if (!fil_check_adress_in_tablespace(space_id, page_no)) { fprintf(stderr, diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index d73d6327d76..9233e861784 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -135,6 +135,8 @@ trx_create( trx->lock_heap = mem_heap_create_in_buffer(256); UT_LIST_INIT(trx->trx_locks); + UT_LIST_INIT(trx->trx_savepoints); + trx->dict_operation_lock_mode = 0; trx->has_search_latch = FALSE; trx->search_latch_timeout = BTR_SEA_TIMEOUT; @@ -807,6 +809,9 @@ trx_commit_off_kernel( mutex_enter(&kernel_mutex); } + /* Free savepoints */ + trx_roll_savepoints_free(trx, NULL); + trx->conc_state = TRX_NOT_STARTED; trx->rseg = NULL; trx->undo_no = ut_dulint_zero; diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index 174ae4cc6bb..f5d207d8bba 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -166,7 +166,7 @@ ut_free( } /************************************************************************** -Frees all allocated memory not freed yet. */ +Frees in shutdown all allocated memory not freed yet. */ void ut_free_all_mem(void) @@ -174,7 +174,7 @@ ut_free_all_mem(void) { ut_mem_block_t* block; - os_fast_mutex_lock(&ut_list_mutex); + os_fast_mutex_free(&ut_list_mutex); while ((block = UT_LIST_GET_FIRST(ut_mem_block_list))) { @@ -187,11 +187,11 @@ ut_free_all_mem(void) free(block); } - os_fast_mutex_unlock(&ut_list_mutex); - - ut_a(ut_total_allocated_memory == 0); - - os_fast_mutex_free(&ut_list_mutex); + if (ut_total_allocated_memory != 0) { + fprintf(stderr, +"InnoDB: Warning: after shutdown total allocated memory is %lu\n", + ut_total_allocated_memory); + } } /************************************************************************** diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index 95037ec3570..06bfb5c45ba 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -53,6 +53,8 @@ ut_get_high32( ulint a) /* in: ulint */ { #if SIZEOF_LONG == 4 + UT_NOT_USED(a); + return 0; #else return(a >> 32); diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index e2dea324ff2..9d1c232e830 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -787,16 +787,6 @@ id id3 100 2 UNLOCK TABLES; DROP TABLE t1; -create table t1 (a char(20), unique (a(5))) type=innodb; -Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the table handler doesn't support unique sub keys -create table t1 (a char(20), index (a(5))) type=innodb; -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` char(20) default NULL, - KEY `a` (`a`) -) TYPE=InnoDB -drop table t1; create temporary table t1 (a int not null auto_increment, primary key(a)) type=innodb; insert into t1 values (NULL),(NULL),(NULL); delete from t1 where a=3; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index dc3c76f1a91..cf203d87c8b 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -471,15 +471,6 @@ select id,id3 from t1; UNLOCK TABLES; DROP TABLE t1; -# -# Test prefix key -# ---error 1089 -create table t1 (a char(20), unique (a(5))) type=innodb; -create table t1 (a char(20), index (a(5))) type=innodb; -show create table t1; -drop table t1; - # # Test using temporary table and auto_increment # diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index fd030fff091..28e61f44111 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -129,12 +129,45 @@ static void innobase_print_error(const char* db_errpfx, char* buffer); /* General functions */ +/********************************************************************** +Save some CPU by testing the value of srv_thread_concurrency in inline +functions. */ +inline +void +innodb_srv_conc_enter_innodb( +/*=========================*/ + trx_t* trx) /* in: transaction handle */ +{ + if (srv_thread_concurrency >= 500) { + + return; + } + + srv_conc_enter_innodb(trx); +} + +/********************************************************************** +Save some CPU by testing the value of srv_thread_concurrency in inline +functions. */ +inline +void +innodb_srv_conc_exit_innodb( +/*========================*/ + trx_t* trx) /* in: transaction handle */ +{ + if (srv_thread_concurrency >= 500) { + + return; + } + + srv_conc_exit_innodb(trx); +} + /********************************************************************** Releases possible search latch and InnoDB thread FIFO ticket. These should be released at each SQL statement end, and also when mysqld passes the control to the client. It does no harm to release these also in the middle of an SQL statement. */ -static inline void innobase_release_stat_resources( @@ -183,7 +216,9 @@ innobase_active_small(void) } /************************************************************************ -Converts an InnoDB error code to a MySQL error code. */ +Converts an InnoDB error code to a MySQL error code and also tells to MySQL +about a possible transaction rollback inside InnoDB caused by a lock wait +timeout or a deadlock. */ static int convert_error_code_to_mysql( @@ -206,10 +241,10 @@ convert_error_code_to_mysql( } else if (error == (int) DB_ERROR) { - return(HA_ERR_NO_ACTIVE_RECORD); + return(-1); /* unspecified error */ } else if (error == (int) DB_DEADLOCK) { - /* Since we roll back the whole transaction, we must + /* Since we rolled back the whole transaction, we must tell it also to MySQL so that MySQL knows to empty the cached binlog for this transaction */ @@ -221,11 +256,10 @@ convert_error_code_to_mysql( } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) { - /* Since we roll back the whole transaction, we must + /* Since we rolled back the whole transaction, we must tell it also to MySQL so that MySQL knows to empty the cached binlog for this transaction */ - if (thd) { ha_rollback(thd); } @@ -271,6 +305,9 @@ convert_error_code_to_mysql( } else if (error == (int) DB_CORRUPTION) { return(HA_ERR_CRASHED); + } else if (error == (int) DB_NO_SAVEPOINT) { + + return(HA_ERR_NO_SAVEPOINT); } else { return(-1); // Unknown error } @@ -941,18 +978,23 @@ innobase_commit( DBUG_ENTER("innobase_commit"); DBUG_PRINT("trans", ("ending transaction")); - /* The flag thd->transaction.all.innodb_active_trans is set to 1 - in ::external_lock and ::start_stmt, and it is only set to 0 in - a commit or a rollback. If it is 0 we know there cannot be resources - to be freed and we can return immediately. */ - - if (thd->transaction.all.innodb_active_trans == 0) { - - DBUG_RETURN(0); - } - trx = check_trx_exists(thd); + /* The flag thd->transaction.all.innodb_active_trans is set to 1 in + ::external_lock, ::start_stmt, and innobase_savepoint, and it is only + set to 0 in a commit or a rollback. If it is 0 we know there cannot be + resources to be freed and we could return immediately. For the time + being we play safe and do the cleanup though there should be nothing + to clean up. */ + + if (thd->transaction.all.innodb_active_trans == 0 + && trx->conc_state != TRX_NOT_STARTED) { + + fprintf(stderr, +"InnoDB: Error: thd->transaction.all.innodb_active_trans == 0\n" +"InnoDB: but trx->conc_state != TRX_NOT_STARTED\n"); + } + if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) { @@ -964,9 +1006,9 @@ innobase_commit( /* If we had reserved the auto-inc lock for some table in this SQL statement we release it now */ - srv_conc_enter_innodb(trx); + innodb_srv_conc_enter_innodb(trx); row_unlock_table_autoinc_for_mysql(trx); - srv_conc_exit_innodb(trx); + innodb_srv_conc_exit_innodb(trx); } /* Store the current undo_no of the transaction so that we know where to roll back if we have to roll back the next @@ -1050,7 +1092,7 @@ innobase_commit_complete( } /********************************************************************* -Rolls back a transaction or the latest SQL statement in an InnoDB database. */ +Rolls back a transaction or the latest SQL statement. */ int innobase_rollback( @@ -1071,25 +1113,27 @@ innobase_rollback( trx = check_trx_exists(thd); if (trx->auto_inc_lock) { - - /* If we had reserved the auto-inc lock for - some table in this SQL statement, we release it now */ - - srv_conc_enter_innodb(trx); + /* If we had reserved the auto-inc lock for some table (if + we come here to roll back the latest SQL statement) we + release it now before a possibly lengthy rollback */ + + innodb_srv_conc_enter_innodb(trx); row_unlock_table_autoinc_for_mysql(trx); - srv_conc_exit_innodb(trx); + innodb_srv_conc_exit_innodb(trx); } - srv_conc_enter_innodb(trx); + innodb_srv_conc_enter_innodb(trx); + + if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle + || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) { - if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { error = trx_rollback_for_mysql(trx); - thd->transaction.all.innodb_active_trans=0; + thd->transaction.all.innodb_active_trans = 0; } else { error = trx_rollback_last_sql_stat_for_mysql(trx); } - srv_conc_exit_innodb(trx); + innodb_srv_conc_exit_innodb(trx); /* Release a possible FIFO ticket and search latch */ innobase_release_stat_resources(trx); @@ -1097,6 +1141,83 @@ innobase_rollback( DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); } +/********************************************************************* +Rolls back a transaction to a savepoint. */ + +int +innobase_rollback_to_savepoint( +/*===========================*/ + /* out: 0 if success, HA_ERR_NO_SAVEPOINT if + no savepoint with the given name */ + THD* thd, /* in: handle to the MySQL thread of the user + whose transaction should be rolled back */ + char* savepoint_name, /* in: savepoint name */ + my_off_t* binlog_cache_pos)/* out: position which corresponds to the + savepoint in the binlog cache of this + transaction, not defined if error */ +{ + ib_longlong mysql_binlog_cache_pos; + int error = 0; + trx_t* trx; + + DBUG_ENTER("innobase_rollback_to_savepoint"); + + trx = check_trx_exists(thd); + + innodb_srv_conc_enter_innodb(trx); + + error = trx_rollback_to_savepoint_for_mysql(trx, savepoint_name, + &mysql_binlog_cache_pos); + innodb_srv_conc_exit_innodb(trx); + + *binlog_cache_pos = (my_off_t)mysql_binlog_cache_pos; + + /* Release a possible FIFO ticket and search latch */ + innobase_release_stat_resources(trx); + + DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); +} + +/********************************************************************* +Sets a transaction savepoint. */ + +int +innobase_savepoint( +/*===============*/ + /* out: always 0, that is, always succeeds */ + THD* thd, /* in: handle to the MySQL thread */ + char* savepoint_name, /* in: savepoint name */ + my_off_t binlog_cache_pos)/* in: offset up to which the current + transaction has cached log entries to its + binlog cache, not defined if no transaction + active, or we are in the autocommit state, or + binlogging is not switched on */ +{ + int error = 0; + trx_t* trx; + + DBUG_ENTER("innobase_savepoint"); + + if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { + /* In the autocommit state there is no sense to set a + savepoint: we return immediate success */ + DBUG_RETURN(0); + } + + trx = check_trx_exists(thd); + + /* Setting a savepoint starts a transaction inside InnoDB since + it allocates resources for it (memory to store the savepoint name, + for example) */ + + thd->transaction.all.innodb_active_trans = 1; + + error = trx_savepoint_for_mysql(trx, savepoint_name, + (ib_longlong)binlog_cache_pos); + + DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); +} + /********************************************************************* Frees a possible InnoDB trx object associated with the current THD. */ @@ -1220,7 +1341,6 @@ ha_innobase::open( { dict_table_t* ib_table; int error = 0; - uint buff_len; char norm_name[1000]; DBUG_ENTER("ha_innobase::open"); @@ -1245,11 +1365,11 @@ ha_innobase::open( fields when packed actually became 1 byte longer, when we also stored the string length as the first byte. */ - buff_len = table->reclength + table->max_key_length + upd_and_key_val_buff_len = table->reclength + table->max_key_length + MAX_REF_PARTS * 3; if (!(mysql_byte*) my_multi_malloc(MYF(MY_WME), - &upd_buff, buff_len, - &key_val_buff, buff_len, + &upd_buff, upd_and_key_val_buff_len, + &key_val_buff, upd_and_key_val_buff_len, NullS)) { free_share(share); DBUG_RETURN(1); @@ -1500,6 +1620,10 @@ innobase_mysql_cmp( case FIELD_TYPE_STRING: case FIELD_TYPE_VAR_STRING: + case FIELD_TYPE_TINY_BLOB: + case FIELD_TYPE_MEDIUM_BLOB: + case FIELD_TYPE_BLOB: + case FIELD_TYPE_LONG_BLOB: ret = my_sortncmp((const char*) a, a_length, (const char*) b, b_length); if (ret < 0) { @@ -1526,7 +1650,7 @@ get_innobase_type_from_mysql_type( /* out: DATA_BINARY, DATA_VARCHAR, ... */ Field* field) /* in: MySQL field */ { - /* The following asserts check that MySQL type code fits in + /* The following asserts check that the MySQL type code fits in 8 bits: this is used in ibuf and also when DATA_NOT_NULL is ORed to the type */ @@ -1537,6 +1661,8 @@ get_innobase_type_from_mysql_type( DBUG_ASSERT((ulint)FIELD_TYPE_DECIMAL < 256); switch (field->type()) { + /* NOTE that we only allow string types in DATA_MYSQL + and DATA_VARMYSQL */ case FIELD_TYPE_VAR_STRING: if (field->flags & BINARY_FLAG) { return(DATA_BINARY); @@ -1607,33 +1733,98 @@ ha_innobase::store_key_val_for_row( KEY_PART_INFO* key_part = key_info->key_part; KEY_PART_INFO* end = key_part + key_info->key_parts; char* buff_start = buff; + enum_field_types mysql_type; + Field* field; + ulint blob_len; + byte* blob_data; + ibool is_null; DBUG_ENTER("store_key_val_for_row"); + /* The format for storing a key field in MySQL is the following: + + 1. If the column can be NULL, then in the first byte we put 1 if the + field value is NULL, 0 otherwise. + + 2. If the column is of a BLOB type (it must be a column prefix field + in this case), then we put the length of the data in the field to the + next 2 bytes, in the little-endian format. If the field is SQL NULL, + then these 2 bytes are set to 0. Note that the length of data in the + field is <= column prefix length. + + 3. In a column prefix field, prefix_len next bytes are reserved for + data. In a normal field the max field length next bytes are reserved + for data. For a VARCHAR(n) the max field length is n. If the stored + value is the SQL NULL then these data bytes are set to 0. */ + + /* We have to zero-fill the 'ref' buffer so that MySQL is able to + use a simple memcmp to compare two key values to determine if they + are equal */ + + bzero(buff, ref_length); + for (; key_part != end; key_part++) { + is_null = FALSE; if (key_part->null_bit) { - /* Store 0 if the key part is a NULL part */ - if (record[key_part->null_offset] & key_part->null_bit) { - *buff++ = 1; - continue; - } - - *buff++ = 0; + *buff = 1; + is_null = TRUE; + } else { + *buff = 0; + } + buff++; } - memcpy(buff, record + key_part->offset, key_part->length); - buff += key_part->length; - } + field = key_part->field; + mysql_type = field->type(); - /* - We have to zero-fill the 'ref' buffer so that MySQL is able to - use a simple memcmp to compare two key values to determine if they - are equal - */ - bzero(buff, (ref_length- (uint) (buff - buff_start))); + if (mysql_type == FIELD_TYPE_TINY_BLOB + || mysql_type == FIELD_TYPE_MEDIUM_BLOB + || mysql_type == FIELD_TYPE_BLOB + || mysql_type == FIELD_TYPE_LONG_BLOB) { + + ut_a(key_part->key_part_flag & HA_PART_KEY); + + if (is_null) { + buff += key_part->length + 2; + + continue; + } + + blob_data = row_mysql_read_blob_ref(&blob_len, + (byte*) (record + + (ulint)get_field_offset(table, field)), + (ulint) field->pack_length()); + + ut_a(get_field_offset(table, field) + == key_part->offset); + if (blob_len > key_part->length) { + blob_len = key_part->length; + } + + /* MySQL reserves 2 bytes for the length and the + storage of the number is little-endian */ + + ut_a(blob_len < 256); + *buff = blob_len; + buff += 2; + + memcpy(buff, blob_data, blob_len); + + buff += key_part->length; + } else { + if (is_null) { + buff += key_part->length; + + continue; + } + memcpy(buff, record + key_part->offset, + key_part->length); + buff += key_part->length; + } + } DBUG_RETURN((uint)(buff - buff_start)); } @@ -1905,9 +2096,9 @@ ha_innobase::write_row( The lock is released at each SQL statement's end. */ - srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(prebuilt->trx); error = row_lock_table_autoinc_for_mysql(prebuilt); - srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(prebuilt->trx); if (error != DB_SUCCESS) { @@ -1918,14 +2109,15 @@ ha_innobase::write_row( dict_table_autoinc_update(prebuilt->table, auto_inc); } else { - srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(prebuilt->trx); if (!prebuilt->trx->auto_inc_lock) { error = row_lock_table_autoinc_for_mysql( prebuilt); if (error != DB_SUCCESS) { - srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb( + prebuilt->trx); error = convert_error_code_to_mysql( error, user_thd); @@ -1939,7 +2131,7 @@ ha_innobase::write_row( auto_inc = dict_table_autoinc_get(prebuilt->table); incremented_auto_inc_counter = TRUE; - srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(prebuilt->trx); /* We can give the new value for MySQL to place in the field */ @@ -1962,11 +2154,11 @@ ha_innobase::write_row( build_template(prebuilt, NULL, table, ROW_MYSQL_WHOLE_ROW); } - srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(prebuilt->trx); error = row_insert_for_mysql((byte*) record, prebuilt); - srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(prebuilt->trx); if (error != DB_SUCCESS) { /* If the insert did not succeed we restore the value of @@ -2037,7 +2229,6 @@ innobase_convert_and_store_changed_col( while (len > 0 && data[len - 1] == ' ') { len--; } - } else if (col_type == DATA_INT) { /* Store integer data in InnoDB in a big-endian format, sign bit negated, if signed */ @@ -2075,9 +2266,11 @@ calc_row_difference( struct st_table* table, /* in: table in MySQL data dictionary */ mysql_byte* upd_buff, /* in: buffer to use */ + ulint buff_len, /* in: buffer length */ row_prebuilt_t* prebuilt, /* in: InnoDB prebuilt struct */ THD* thd) /* in: user thread */ { + mysql_byte* original_upd_buff = upd_buff; Field* field; uint n_fields; ulint o_len; @@ -2159,12 +2352,13 @@ calc_row_difference( (prebuilt->table->cols + i)->clust_pos; n_changed++; } - ; } uvect->n_fields = n_changed; uvect->info_bits = 0; + ut_a(buf <= (byte*)original_upd_buff + buff_len); + return(0); } @@ -2213,17 +2407,19 @@ ha_innobase::update_row( (uses upd_buff of the handle) */ calc_row_difference(uvect, (mysql_byte*) old_row, new_row, table, - upd_buff, prebuilt, user_thd); + upd_buff, (ulint)upd_and_key_val_buff_len, + prebuilt, user_thd); + /* This is not a delete */ prebuilt->upd_node->is_delete = FALSE; assert(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW); - srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(prebuilt->trx); error = row_update_for_mysql((byte*) old_row, prebuilt); - srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(prebuilt->trx); error = convert_error_code_to_mysql(error, user_thd); @@ -2267,11 +2463,11 @@ ha_innobase::delete_row( prebuilt->upd_node->is_delete = TRUE; - srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(prebuilt->trx); error = row_update_for_mysql((byte*) record, prebuilt); - srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(prebuilt->trx); error = convert_error_code_to_mysql(error, user_thd); @@ -2459,10 +2655,11 @@ ha_innobase::index_read( prebuilt->search_tuple */ row_sel_convert_mysql_key_to_innobase(prebuilt->search_tuple, - (byte*) key_val_buff, - index, - (byte*) key_ptr, - (ulint) key_len); + (byte*) key_val_buff, + (ulint)upd_and_key_val_buff_len, + index, + (byte*) key_ptr, + (ulint) key_len); } else { /* We position the cursor to the last or the first entry in the index */ @@ -2484,11 +2681,11 @@ ha_innobase::index_read( last_match_mode = match_mode; - srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(prebuilt->trx); ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0); - srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(prebuilt->trx); if (ret == DB_SUCCESS) { error = 0; @@ -2632,11 +2829,11 @@ ha_innobase::general_fetch( ut_a(prebuilt->trx == (trx_t*) current_thd->transaction.all.innobase_tid); - srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(prebuilt->trx); ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode, direction); - srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(prebuilt->trx); if (ret == DB_SUCCESS) { error = 0; @@ -2939,7 +3136,6 @@ ha_innobase::position( } } - /********************************************************************* Creates a table definition to an InnoDB database. */ static @@ -2958,6 +3154,8 @@ create_table_def( ulint col_type; ulint nulls_allowed; ulint unsigned_type; + ulint binary_type; + ulint nonlatin1_type; ulint i; DBUG_ENTER("create_table_def"); @@ -2986,9 +3184,23 @@ create_table_def( unsigned_type = 0; } + if (strcmp(default_charset_info->name, "latin1") != 0) { + nonlatin1_type = DATA_NONLATIN1; + } else { + nonlatin1_type = 0; + } + + if (field->flags & BINARY_FLAG) { + binary_type = DATA_BINARY_TYPE; + nonlatin1_type = 0; + } else { + binary_type = 0; + } + dict_mem_table_add_col(table, (char*) field->field_name, col_type, (ulint)field->type() - | nulls_allowed | unsigned_type, + | nulls_allowed | unsigned_type + | nonlatin1_type | binary_type, field->pack_length(), 0); } @@ -3011,6 +3223,7 @@ create_index( const char* table_name, /* in: table name */ uint key_num) /* in: index number */ { + Field* field; dict_index_t* index; int error; ulint n_fields; @@ -3020,6 +3233,7 @@ create_index( ulint col_type; ulint prefix_len; ulint i; + ulint j; DBUG_ENTER("create_index"); @@ -3046,31 +3260,63 @@ create_index( for (i = 0; i < n_fields; i++) { key_part = key->key_part + i; - if (key_part->length != key_part->field->pack_length()) { + /* (The flag HA_PART_KEY denotes in MySQL a column prefix + field in an index: we only store a specified number of first + bytes of the column to the index field.) The flag does not + seem to be properly set by MySQL. Let us fall back on testing + the length of the key part versus the column. */ + + field = NULL; + for (j = 0; j < form->fields; j++) { + + field = form->field[j]; + + if (strlen(field->field_name) + == strlen(key_part->field->field_name) + && 0 == ut_cmp_in_lower_case( + (char*)field->field_name, + (char*)key_part->field->field_name, + strlen(field->field_name))) { + /* Found the corresponding column */ + + break; + } + } + + ut_a(j < form->fields); + + col_type = get_innobase_type_from_mysql_type(key_part->field); + + if (DATA_BLOB == col_type + || key_part->length < field->pack_length()) { + prefix_len = key_part->length; - col_type = get_innobase_type_from_mysql_type( - key_part->field); if (col_type == DATA_INT || col_type == DATA_FLOAT || col_type == DATA_DOUBLE || col_type == DATA_DECIMAL) { fprintf(stderr, "InnoDB: error: MySQL is trying to create a column prefix index field\n" -"InnoDB: on an inappropriate data type %lu. Table name %s, column name %s.\n", - col_type, table_name, - key_part->field->field_name); +"InnoDB: on an inappropriate data type. Table name %s, column name %s.\n", + table_name, key_part->field->field_name); prefix_len = 0; } } else { prefix_len = 0; - } + } + + if (prefix_len >= DICT_MAX_COL_PREFIX_LEN) { + DBUG_RETURN(-1); + } /* We assume all fields should be sorted in ascending order, hence the '0': */ + dict_mem_index_add_field(index, - (char*) key_part->field->field_name, 0); + (char*) key_part->field->field_name, + 0, prefix_len); } error = row_create_index_for_mysql(index, trx); @@ -3536,6 +3782,8 @@ ha_innobase::records_in_range( table->reclength + table->max_key_length + 100, MYF(MY_WME)); + ulint buff2_len = table->reclength + + table->max_key_length + 100; dtuple_t* range_start; dtuple_t* range_end; ib_longlong n_rows; @@ -3572,12 +3820,15 @@ ha_innobase::records_in_range( dict_index_copy_types(range_end, index, key->key_parts); row_sel_convert_mysql_key_to_innobase( - range_start, (byte*) key_val_buff, index, + range_start, (byte*) key_val_buff, + (ulint)upd_and_key_val_buff_len, + index, (byte*) start_key, (ulint) start_key_len); row_sel_convert_mysql_key_to_innobase( - range_end, (byte*) key_val_buff2, index, + range_end, (byte*) key_val_buff2, + buff2_len, index, (byte*) end_key, (ulint) end_key_len); @@ -3787,8 +4038,32 @@ ha_innobase::info( } for (i = 0; i < table->keys; i++) { + if (index == NULL) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: table %s contains less indexes inside InnoDB\n" +"InnoDB: than are defined in the MySQL .frm file. Have you mixed up\n" +"InnoDB: .frm files from different installations? See section\n" +"InnoDB: 15.1 at http://www.innodb.com/ibman.html\n", + ib_table->name); + break; + } + for (j = 0; j < table->key_info[i].key_parts; j++) { + if (j + 1 > index->n_uniq) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: index %s of %s has %lu columns unique inside InnoDB\n" +"InnoDB: but MySQL is asking statistics for %lu columns. Have you mixed up\n" +"InnoDB: .frm files from different installations? See section\n" +"InnoDB: 15.1 at http://www.innodb.com/ibman.html\n", + index->name, + ib_table->name, index->n_uniq, + j + 1); + break; + } + if (index->stat_n_diff_key_vals[j + 1] == 0) { rec_per_key = records; @@ -4046,10 +4321,11 @@ ha_innobase::reset(void) } /********************************************************************** -MySQL calls this function at the start of each SQL statement. Inside LOCK -TABLES the ::external_lock method does not work to mark SQL statement -borders. Note also a special case: if a temporary table is created inside -LOCK TABLES, MySQL has not called external_lock() at all on that table. */ +MySQL calls this function at the start of each SQL statement inside LOCK +TABLES. Inside LOCK TABLES the ::external_lock method does not work to +mark SQL statement borders. Note also a special case: if a temporary table +is created inside LOCK TABLES, MySQL has not called external_lock() at all +on that table. */ int ha_innobase::start_stmt( @@ -4448,9 +4724,9 @@ ha_innobase::innobase_read_and_init_auto_inc( return(0); } - srv_conc_enter_innodb(prebuilt->trx); + innodb_srv_conc_enter_innodb(prebuilt->trx); error = row_lock_table_autoinc_for_mysql(prebuilt); - srv_conc_exit_innodb(prebuilt->trx); + innodb_srv_conc_exit_innodb(prebuilt->trx); if (error != DB_SUCCESS) { error = convert_error_code_to_mysql(error, user_thd); diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 1a9b1b16c64..bfa2687b87a 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -52,6 +52,9 @@ class ha_innobase: public handler byte* key_val_buff; /* buffer used in converting search key values from MySQL format to Innodb format */ + ulong upd_and_key_val_buff_len; + /* the length of each of the previous + two buffers */ ulong int_table_flags; uint primary_key; uint last_dup_key; @@ -83,13 +86,15 @@ class ha_innobase: public handler public: ha_innobase(TABLE *table): handler(table), int_table_flags(HA_REC_NOT_IN_SEQ | - HA_KEYPOS_TO_RNDPOS | HA_LASTKEY_ORDER | - HA_NULL_KEY | HA_CAN_SQL_HANDLER | + HA_KEYPOS_TO_RNDPOS | + HA_LASTKEY_ORDER | + HA_NULL_KEY | + HA_BLOB_KEY | + HA_CAN_SQL_HANDLER | HA_NOT_EXACT_COUNT | HA_NO_WRITE_DELAYED | HA_PRIMARY_KEY_IN_READ_INDEX | HA_DROP_BEFORE_CREATE | - HA_NO_PREFIX_CHAR_KEYS | HA_TABLE_SCAN_ON_INDEX), last_dup_key((uint) -1), start_of_scan(0) @@ -217,6 +222,14 @@ int innobase_report_binlog_offset_and_commit( int innobase_commit_complete( void* trx_handle); int innobase_rollback(THD *thd, void* trx_handle); +int innobase_rollback_to_savepoint( + THD* thd, + char* savepoint_name, + my_off_t* binlog_cache_pos); +int innobase_savepoint( + THD* thd, + char* savepoint_name, + my_off_t binlog_cache_pos); int innobase_close_connection(THD *thd); int innobase_drop_database(char *path); int innodb_show_status(THD* thd); diff --git a/sql/handler.cc b/sql/handler.cc index cae1777e958..4ea5bc0e9f5 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -379,7 +379,6 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) trans->innodb_active_trans=0; if (trans == &thd->transaction.all) operation_done= transaction_commited= 1; - } #endif #ifdef HAVE_QUERY_CACHE @@ -447,6 +446,70 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) DBUG_RETURN(error); } + +/* +Rolls the current transaction back to a savepoint. +Return value: 0 if success, 1 if there was not a savepoint of the given +name. +*/ + +int ha_rollback_to_savepoint(THD *thd, char *savepoint_name) +{ + my_off_t binlog_cache_pos=0; + bool operation_done=0; + int error=0; + DBUG_ENTER("ha_rollback_to_savepoint"); +#ifdef USING_TRANSACTIONS + if (opt_using_transactions) + { +#ifdef HAVE_INNOBASE_DB + /* + Retrieve the trans_log binlog cache position corresponding to the + savepoint, and if the rollback is successful inside InnoDB reset the write + position in the binlog cache to what it was at the savepoint. + */ + if ((error=innobase_rollback_to_savepoint(thd, savepoint_name, + &binlog_cache_pos))) + { + my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error); + error=1; + } + else + reinit_io_cache(&thd->transaction.trans_log, WRITE_CACHE, + binlog_cache_pos, 0, 0); + operation_done=1; +#endif + if (operation_done) + statistic_increment(ha_rollback_count,&LOCK_status); + } +#endif /* USING_TRANSACTIONS */ + + DBUG_RETURN(error); +} + + +/* +Sets a transaction savepoint. +Return value: always 0, that is, succeeds always +*/ + +int ha_savepoint(THD *thd, char *savepoint_name) +{ + my_off_t binlog_cache_pos=0; + int error=0; + DBUG_ENTER("ha_savepoint"); +#ifdef USING_TRANSACTIONS + if (opt_using_transactions) + { + binlog_cache_pos=my_b_tell(&thd->transaction.trans_log); +#ifdef HAVE_INNOBASE_DB + innobase_savepoint(thd,savepoint_name, binlog_cache_pos); +#endif + } +#endif /* USING_TRANSACTIONS */ + DBUG_RETURN(error); +} + bool ha_flush_logs() { bool result=0; diff --git a/sql/handler.h b/sql/handler.h index fbad36bffdd..41f6fdc656a 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -376,6 +376,8 @@ int ha_commit_complete(THD *thd); int ha_release_temporary_latches(THD *thd); int ha_commit_trans(THD *thd, THD_TRANS *trans); int ha_rollback_trans(THD *thd, THD_TRANS *trans); +int ha_rollback_to_savepoint(THD *thd, char *savepoint_name); +int ha_savepoint(THD *thd, char *savepoint_name); int ha_autocommit_or_rollback(THD *thd, int error); void ha_set_spin_retries(uint retries); bool ha_flush_logs(void); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 7d931399782..0618f04a79b 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -53,8 +53,9 @@ enum enum_sql_command { SQLCOM_REPAIR, SQLCOM_REPLACE, SQLCOM_REPLACE_SELECT, SQLCOM_CREATE_FUNCTION, SQLCOM_DROP_FUNCTION, SQLCOM_REVOKE,SQLCOM_OPTIMIZE, SQLCOM_CHECK, - SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, - SQLCOM_ROLLBACK, SQLCOM_COMMIT, SQLCOM_SAVEPOINT, + SQLCOM_FLUSH, SQLCOM_KILL, SQLCOM_ANALYZE, + SQLCOM_ROLLBACK, SQLCOM_ROLLBACK_TO_SAVEPOINT, + SQLCOM_COMMIT, SQLCOM_SAVEPOINT, SQLCOM_SLAVE_START, SQLCOM_SLAVE_STOP, SQLCOM_BEGIN, SQLCOM_LOAD_MASTER_TABLE, SQLCOM_CHANGE_MASTER, SQLCOM_RENAME_TABLE, SQLCOM_BACKUP_TABLE, SQLCOM_RESTORE_TABLE, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3a8895ab120..bb06713ec4c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2536,8 +2536,22 @@ mysql_execute_command(void) res= -1; thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE); break; + case SQLCOM_ROLLBACK_TO_SAVEPOINT: + if (!ha_rollback_to_savepoint(thd, lex->savepoint_name)) + { + if (thd->options & OPTION_STATUS_NO_TRANS_UPDATE) + send_warning(&thd->net,ER_WARNING_NOT_COMPLETE_ROLLBACK,0); + else + send_ok(&thd->net); + } + else + res= -1; + break; case SQLCOM_SAVEPOINT: - send_ok(&thd->net); + if (!ha_savepoint(thd, lex->savepoint_name)) + send_ok(&thd->net); + else + res= -1; break; default: /* Impossible */ send_ok(&thd->net); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2ef0992cdf7..4a41ad32dcc 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3922,11 +3922,10 @@ rollback: ROLLBACK_SYM { Lex->sql_command = SQLCOM_ROLLBACK; - Lex->savepoint_name = NULL; } | ROLLBACK_SYM TO_SYM SAVEPOINT_SYM ident { - Lex->sql_command = SQLCOM_ROLLBACK; + Lex->sql_command = SQLCOM_ROLLBACK_TO_SAVEPOINT; Lex->savepoint_name = $4.str; }; savepoint: From 80edc81ed0dbab0a2464c4cbf49b23c35e9b4011 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sun, 15 Jun 2003 12:01:51 +0200 Subject: [PATCH 028/237] Simplified a test. thd->enter_cond() and exit_cond(), so that the I/O thread accepts to stop when it's waiting for relay log space. Reset ignore_log_space_limit to 0 when the SQL thread terminates. --- mysql-test/r/rpl_relayspace.result | 10 ++++++-- mysql-test/t/rpl_relayspace-slave.opt | 2 +- mysql-test/t/rpl_relayspace.test | 33 +++++++++++++-------------- sql/slave.cc | 15 +++++++----- 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/rpl_relayspace.result b/mysql-test/r/rpl_relayspace.result index 5e552ef7400..721c6a882bd 100644 --- a/mysql-test/r/rpl_relayspace.result +++ b/mysql-test/r/rpl_relayspace.result @@ -6,8 +6,14 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; stop slave; create table t1 (a int); +drop table t1; +create table t1 (a int); +drop table t1; +reset slave; +start slave io_thread; +stop slave io_thread; reset slave; start slave; -select master_pos_wait('master-bin.001',5000,45)=-1; -master_pos_wait('master-bin.001',5000,45)=-1 +select master_pos_wait('master-bin.001',200,6)=-1; +master_pos_wait('master-bin.001',200,6)=-1 0 diff --git a/mysql-test/t/rpl_relayspace-slave.opt b/mysql-test/t/rpl_relayspace-slave.opt index 9365a2a0a26..05cb01731d2 100644 --- a/mysql-test/t/rpl_relayspace-slave.opt +++ b/mysql-test/t/rpl_relayspace-slave.opt @@ -1 +1 @@ - -O relay_log_space_limit=1024 \ No newline at end of file + -O relay_log_space_limit=10 \ No newline at end of file diff --git a/mysql-test/t/rpl_relayspace.test b/mysql-test/t/rpl_relayspace.test index 8d4f01339c7..bb82781b511 100644 --- a/mysql-test/t/rpl_relayspace.test +++ b/mysql-test/t/rpl_relayspace.test @@ -1,33 +1,32 @@ -# The slave is started with relay_log_space_limit=1024 bytes, -# to force the deadlock +# The slave is started with relay_log_space_limit=10 bytes, +# to force the deadlock after one event. source include/master-slave.inc; connection slave; stop slave; connection master; +# This will generate a master's binlog > 10 bytes create table t1 (a int); -let $1=200; -disable_query_log; -while ($1) -{ -# eval means expand $ expressions - eval insert into t1 values( $1 ); - dec $1; -} -# This will generate one 10kB master's binlog -enable_query_log; -save_master_pos; +drop table t1; +create table t1 (a int); +drop table t1; connection slave; reset slave; +start slave io_thread; +# Give the I/O thread time to block. +sleep 2; +# A bug caused the I/O thread to refuse stopping. +stop slave io_thread; +reset slave; start slave; # The I/O thread stops filling the relay log when -# it's 1kB. And the SQL thread cannot purge this relay log +# it's >10b. And the SQL thread cannot purge this relay log # as purge is done only when the SQL thread switches to another # relay log, which does not exist here. # So we should have a deadlock. # if it is not resolved automatically we'll detect -# it with master_pos_wait that waits for farther than 1kB; -# it will timeout after 45 seconds; +# it with master_pos_wait that waits for farther than 1Ob; +# it will timeout after 10 seconds; # also the slave will probably not cooperate to shutdown # (as 2 threads are locked) -select master_pos_wait('master-bin.001',5000,45)=-1; +select master_pos_wait('master-bin.001',200,6)=-1; diff --git a/sql/slave.cc b/sql/slave.cc index 74005c65672..73f1073ae09 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1392,18 +1392,18 @@ static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli) { bool slave_killed=0; MASTER_INFO* mi = rli->mi; - const char* save_proc_info; THD* thd = mi->io_thd; DBUG_ENTER("wait_for_relay_log_space"); pthread_mutex_lock(&rli->log_space_lock); - save_proc_info = thd->proc_info; - thd->proc_info = "Waiting for relay log space to free"; + const char* save_proc_info= thd->enter_cond(&rli->log_space_cond, + &rli->log_space_lock, + "Waiting for relay log space to free"); while (rli->log_space_limit < rli->log_space_total && !(slave_killed=io_slave_killed(thd,mi)) && !rli->ignore_log_space_limit) pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock); - thd->proc_info = save_proc_info; + thd->exit_cond(save_proc_info); pthread_mutex_unlock(&rli->log_space_lock); DBUG_RETURN(slave_killed); } @@ -2445,6 +2445,8 @@ reconnect done to recover from failed read"); for no reason, but this function will do a clean read, notice the clean value and exit immediately. */ + DBUG_PRINT("info", ("ignore_log_space_limit=%d", (int) + mi->rli.ignore_log_space_limit)); if (mi->rli.log_space_limit && mi->rli.log_space_limit < mi->rli.log_space_total && !mi->rli.ignore_log_space_limit) @@ -2626,6 +2628,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \ pthread_mutex_unlock(&rli->data_lock); DBUG_PRINT("info",("Signaling possibly waiting master_pos_wait() functions")); pthread_cond_broadcast(&rli->data_cond); + rli->ignore_log_space_limit= 0; /* don't need any lock */ rli->save_temporary_tables = thd->temporary_tables; /* @@ -3268,8 +3271,8 @@ Log_event* next_event(RELAY_LOG_INFO* rli) log), and also when the SQL thread starts. We should also reset ignore_log_space_limit to 0 when the user does RESET SLAVE, but in fact, no need as RESET SLAVE requires that the slave - be stopped, and when the SQL thread is later restarted - ignore_log_space_limit will be reset to 0. + be stopped, and the SQL thread sets ignore_log_space_limit to 0 when + it stops. */ pthread_mutex_lock(&rli->log_space_lock); // prevent the I/O thread from blocking next times From 95ffe2d0cac112d495d49a3da65d10f0883ca874 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sun, 15 Jun 2003 23:23:04 +0300 Subject: [PATCH 029/237] handler.h, ha_innodb.h, ha_innodb.cc: Cleanup; remove compiler warning on Windows --- sql/ha_innodb.cc | 26 +++++++++++++++----------- sql/ha_innodb.h | 3 ++- sql/handler.h | 3 ++- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 28e61f44111..081b9a85c5c 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -43,7 +43,9 @@ InnoDB */ pthread_mutex_t innobase_mutex; /* Store MySQL definition of 'byte': in Linux it is char while InnoDB -uses unsigned char */ +uses unsigned char; the header univ.i which we include next defines +'byte' as a macro which expands to 'unsigned char' */ + typedef byte mysql_byte; #define INSIDE_HA_INNOBASE_CC @@ -1716,8 +1718,7 @@ get_innobase_type_from_mysql_type( } /*********************************************************************** -Stores a key value for a row to a buffer. This must currently only be used -to store a row reference to the 'ref' buffer of this table handle! */ +Stores a key value for a row to a buffer. */ uint ha_innobase::store_key_val_for_row( @@ -1725,8 +1726,8 @@ ha_innobase::store_key_val_for_row( /* out: key value length as stored in buff */ uint keynr, /* in: key number */ char* buff, /* in/out: buffer for the key value (in MySQL - format); currently this MUST be the 'ref' - buffer! */ + format) */ + uint buff_len,/* in: buffer length */ const mysql_byte* record)/* in: row in MySQL format */ { KEY* key_info = table->key_info + keynr; @@ -1757,11 +1758,11 @@ ha_innobase::store_key_val_for_row( for data. For a VARCHAR(n) the max field length is n. If the stored value is the SQL NULL then these data bytes are set to 0. */ - /* We have to zero-fill the 'ref' buffer so that MySQL is able to - use a simple memcmp to compare two key values to determine if they - are equal */ + /* We have to zero-fill the buffer so that MySQL is able to use a + simple memcmp to compare two key values to determine if they are + equal. MySQL does this to compare contents of two 'ref' values. */ - bzero(buff, ref_length); + bzero(buff, buff_len); for (; key_part != end; key_part++) { is_null = FALSE; @@ -1808,7 +1809,7 @@ ha_innobase::store_key_val_for_row( storage of the number is little-endian */ ut_a(blob_len < 256); - *buff = blob_len; + *((byte*)buff) = (byte)blob_len; buff += 2; memcpy(buff, blob_data, blob_len); @@ -1826,6 +1827,8 @@ ha_innobase::store_key_val_for_row( } } + ut_a(buff <= buff_start + buff_len); + DBUG_RETURN((uint)(buff - buff_start)); } @@ -3122,7 +3125,8 @@ ha_innobase::position( memcpy(ref, prebuilt->row_id, len); } else { - len = store_key_val_for_row(primary_key, (char*) ref, record); + len = store_key_val_for_row(primary_key, (char*)ref, + ref_length, record); } /* Since we do not store len to the buffer 'ref', we must assume diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index bfa2687b87a..a3fe56f6bcd 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -76,7 +76,8 @@ class ha_innobase: public handler longlong auto_inc_counter_for_this_stat; ulong max_row_length(const byte *buf); - uint store_key_val_for_row(uint keynr, char* buff, const byte* record); + uint store_key_val_for_row(uint keynr, char* buff, uint buff_len, + const byte* record); int update_thd(THD* thd); int change_active_index(uint keynr); int general_fetch(byte* buf, uint direction, uint match_mode); diff --git a/sql/handler.h b/sql/handler.h index 41f6fdc656a..56f63d1d521 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -189,7 +189,8 @@ class handler :public Sql_alloc public: byte *ref; /* Pointer to current row */ byte *dupp_ref; /* Pointer to dupp row */ - uint ref_length; /* Length of ref (1-8) */ + uint ref_length; /* Length of ref (1-8 or the clustered + key length) */ uint block_size; /* index block size */ ha_rows records; /* Records i datafilen */ ha_rows deleted; /* Deleted records */ From 29796e6240f3d0c8979d09f9a15a978317ca9f39 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Mon, 16 Jun 2003 00:39:46 +0300 Subject: [PATCH 030/237] row0mysql.c, dict0dict.ic: Cleanup ha_innodb.cc, data0type.h: Make sure non-latin1 users can downgrade from 4.0.14 to an earlier version if they have not created DATA_BLOB column prefix indexes --- innobase/include/data0type.h | 6 +++--- innobase/include/dict0dict.ic | 1 - innobase/row/row0mysql.c | 9 +++++++++ sql/ha_innodb.cc | 3 ++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/innobase/include/data0type.h b/innobase/include/data0type.h index 5e28f657f0c..4da686bf2e1 100644 --- a/innobase/include/data0type.h +++ b/innobase/include/data0type.h @@ -79,9 +79,9 @@ be less than 256 */ string, this is ORed to the precise type: this only holds for tables created with >= MySQL-4.0.14 */ -#define DATA_NONLATIN1 2048 /* if the data type is a character string - of a non-latin1 type, this is ORed to the - precise type: this only holds for tables +#define DATA_NONLATIN1 2048 /* if the data type is a DATA_BLOB (actually + TEXT) of a non-latin1 type, this is ORed to + the precise type: this only holds for tables created with >= MySQL-4.0.14 */ /*-------------------------------------------*/ diff --git a/innobase/include/dict0dict.ic b/innobase/include/dict0dict.ic index 71ea67117a7..c5982c162a7 100644 --- a/innobase/include/dict0dict.ic +++ b/innobase/include/dict0dict.ic @@ -203,7 +203,6 @@ dict_index_get_n_fields( { ut_ad(index); ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - ut_ad(index->cached); return(index->n_fields); } diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 61ba9111b91..dc2a50c4f0c 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -507,6 +507,7 @@ row_get_prebuilt_insert_row( ins_node_t* node; dtuple_t* row; dict_table_t* table = prebuilt->table; + ulint i; ut_ad(prebuilt && table && prebuilt->trx); @@ -530,6 +531,14 @@ row_get_prebuilt_insert_row( dict_table_copy_types(row, table); + /* We init the value of every field to the SQL NULL to avoid + a debug assertion from failing */ + + for (i = 0; i < dtuple_get_n_fields(row); i++) { + + dtuple_get_nth_field(row, i)->len = UNIV_SQL_NULL; + } + ins_node_set_new_row(node, row); prebuilt->ins_graph = diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 081b9a85c5c..795cffc0776 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3188,7 +3188,8 @@ create_table_def( unsigned_type = 0; } - if (strcmp(default_charset_info->name, "latin1") != 0) { + if (col_type == DATA_BLOB + && strcmp(default_charset_info->name, "latin1") != 0) { nonlatin1_type = DATA_NONLATIN1; } else { nonlatin1_type = 0; From 3f33f17114cbd7673a03d68cdc7595cab19570b0 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Mon, 16 Jun 2003 15:49:54 +0200 Subject: [PATCH 031/237] Fix for nightly build test failure (test update). More messages. Testcase for bug 651. --- client/mysqltest.c | 3 ++- mysql-test/r/rpl_loaddata.result | 3 --- mysql-test/r/rpl_master_pos_wait.result | 8 ++++++-- mysql-test/t/rpl000001.test | 4 ++-- mysql-test/t/rpl_loaddata.test | 8 ++------ mysql-test/t/rpl_master_pos_wait.test | 10 ++++++++-- sql/slave.cc | 13 +++++++++++-- 7 files changed, 31 insertions(+), 18 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index f6c999b18e4..f5afa0fa0df 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -996,7 +996,8 @@ 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("Error on slave while syncing with master"); + die("line %u: could not sync with master ('%s' returned NULL)", + start_lineno, query_buf); mysql_free_result(res); last_result=0; if (rpl_parse) diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index 844a9d66cb3..b5154ca95cf 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -25,6 +25,3 @@ drop table t3; create table t1(a int, b int, unique(b)); insert into t1 values(1,10); load data infile '../../std_data/rpl_loaddata.dat' into table t1; -show status like 'slave_running'; -Variable_name Value -Slave_running OFF diff --git a/mysql-test/r/rpl_master_pos_wait.result b/mysql-test/r/rpl_master_pos_wait.result index 22c7aef621c..cb6ee31a54d 100644 --- a/mysql-test/r/rpl_master_pos_wait.result +++ b/mysql-test/r/rpl_master_pos_wait.result @@ -4,6 +4,10 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; slave start; -select master_pos_wait('master-bin.999999',0,10); -master_pos_wait('master-bin.999999',0,10) +select master_pos_wait('master-bin.999999',0,2); +master_pos_wait('master-bin.999999',0,2) -1 + select master_pos_wait('master-bin.999999',0); +stop slave sql_thread; +master_pos_wait('master-bin.999999',0) +NULL diff --git a/mysql-test/t/rpl000001.test b/mysql-test/t/rpl000001.test index 4ffd7d1d78e..ebce3d0ac94 100644 --- a/mysql-test/t/rpl000001.test +++ b/mysql-test/t/rpl000001.test @@ -90,8 +90,8 @@ connection master; --error 1053; reap; connection slave; -sync_with_master; -#give the slave a chance to exit +# The SQL slave thread should now have stopped because the query was killed on +# the master (so it has a non-zero error code in the binlog). wait_for_slave_to_stop; # The following test can't be done because the result of Pos will differ diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test index dc4eadda192..96a4eb3fb76 100644 --- a/mysql-test/t/rpl_loaddata.test +++ b/mysql-test/t/rpl_loaddata.test @@ -42,9 +42,5 @@ load data infile '../../std_data/rpl_loaddata.dat' into table t1; save_master_pos; connection slave; -# don't sync_with_master because the slave SQL thread should be stopped because -# of the error so MASTER_POS_WAIT() will not return; just sleep and hope the -# slave SQL thread will have had time to stop. - -sleep 1; -show status like 'slave_running'; +# The SQL slave thread should be stopped now. +wait_for_slave_to_stop; diff --git a/mysql-test/t/rpl_master_pos_wait.test b/mysql-test/t/rpl_master_pos_wait.test index a6aae222a89..24479636c91 100644 --- a/mysql-test/t/rpl_master_pos_wait.test +++ b/mysql-test/t/rpl_master_pos_wait.test @@ -5,5 +5,11 @@ save_master_pos; connection slave; sync_with_master; # Ask for a master log that has certainly not been reached yet -# timeout= 10 seconds -select master_pos_wait('master-bin.999999',0,10); +# timeout= 2 seconds +select master_pos_wait('master-bin.999999',0,2); +# Testcase for bug 651 (master_pos_wait() hangs if slave idle and STOP SLAVE). +send select master_pos_wait('master-bin.999999',0); +connection slave1; +stop slave sql_thread; +connection slave; +reap; diff --git a/sql/slave.cc b/sql/slave.cc index 73f1073ae09..dc9ce9715d8 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2445,8 +2445,17 @@ reconnect done to recover from failed read"); for no reason, but this function will do a clean read, notice the clean value and exit immediately. */ - DBUG_PRINT("info", ("ignore_log_space_limit=%d", (int) - mi->rli.ignore_log_space_limit)); +#ifndef DBUG_OFF + { + char llbuf1[22], llbuf2[22]; + DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \ +ignore_log_space_limit=%d", + llstr(mi->rli.log_space_limit,llbuf1), + llstr(mi->rli.log_space_total,llbuf2), + (int) mi->rli.ignore_log_space_limit)); + } +#endif + if (mi->rli.log_space_limit && mi->rli.log_space_limit < mi->rli.log_space_total && !mi->rli.ignore_log_space_limit) From 9b3dccd662590e9e525d936f80e4a936c2ad5308 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 16 Jun 2003 19:07:48 +0200 Subject: [PATCH 032/237] reverting Monty's "fix" that turned a warning into an error. --- myisam/mi_open.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/myisam/mi_open.c b/myisam/mi_open.c index 99b97db3fbd..59fae36ac33 100644 --- a/myisam/mi_open.c +++ b/myisam/mi_open.c @@ -188,11 +188,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) share->state_diff_length=len-MI_STATE_INFO_SIZE; if (share->state.header.fulltext_keys) - { - /* Not supported in this version */ - my_errno= HA_ERR_UNSUPPORTED; - goto err; - } + fprintf(stderr, "Warning: table file %s was created in MySQL 4.1+, use REPAIR TABLE ... USE_FRM to recreate it as a valid MySQL 4.0 table\n", name_buff); + mi_state_info_read(disk_cache, &share->state); len= mi_uint2korr(share->state.header.base_info_length); if (len != MI_BASE_INFO_SIZE) From b387b5add96fc092277ef79f57103ce15e3eb32f Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 16 Jun 2003 23:05:45 +0200 Subject: [PATCH 033/237] fulltext and left join bug fixed --- mysql-test/r/fulltext.result | 3 +++ mysql-test/r/fulltext_left_join.result | 11 +++++++++++ mysql-test/t/fulltext.test | 1 + mysql-test/t/fulltext_left_join.test | 12 ++++++++++++ sql/item_func.cc | 3 +++ sql/sql_select.cc | 3 +++ 6 files changed, 33 insertions(+) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index eaaaf9c8880..6f15b2eb973 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -5,6 +5,9 @@ INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'), ('Only MyISAM tables','support collections'), ('Function MATCH ... AGAINST()','is used to do a search'), ('Full-text search in MySQL', 'implements vector space model'); +explain select * from t1 where MATCH(a,b) AGAINST ("collections"); +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where select * from t1 where MATCH(a,b) AGAINST ("collections"); a b Only MyISAM tables support collections diff --git a/mysql-test/r/fulltext_left_join.result b/mysql-test/r/fulltext_left_join.result index abc63358dbe..6875a517718 100644 --- a/mysql-test/r/fulltext_left_join.result +++ b/mysql-test/r/fulltext_left_join.result @@ -31,3 +31,14 @@ match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE) 1 0 drop table t1, t2; +create table t1 (venue_id int(11) default null, venue_text varchar(255) default null, dt datetime default null) type=myisam; +insert into t1 (venue_id, venue_text, dt) values (1, 'a1', '2003-05-23 19:30:00'),(null, 'a2', '2003-05-23 19:30:00'); +create table t2 (name varchar(255) not null default '', entity_id int(11) not null auto_increment, primary key (entity_id), fulltext key name (name)) type=myisam; +insert into t2 (name, entity_id) values ('aberdeen town hall', 1), ('glasgow royal concert hall', 2), ('queen\'s hall, edinburgh', 3); +select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen' in boolean mode) and dt = '2003-05-23 19:30:00'; +venue_id venue_text dt name entity_id +1 a1 2003-05-23 19:30:00 aberdeen town hall 1 +select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen') and dt = '2003-05-23 19:30:00'; +venue_id venue_text dt name entity_id +1 a1 2003-05-23 19:30:00 aberdeen town hall 1 +drop table t1,t2; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 128af680854..1b85f5903df 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -13,6 +13,7 @@ INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'), # nl search +explain select * from t1 where MATCH(a,b) AGAINST ("collections"); select * from t1 where MATCH(a,b) AGAINST ("collections"); select * from t1 where MATCH(a,b) AGAINST ("indexes"); select * from t1 where MATCH(a,b) AGAINST ("indexes collections"); diff --git a/mysql-test/t/fulltext_left_join.test b/mysql-test/t/fulltext_left_join.test index bcf7cbcc505..da4df13bc0c 100644 --- a/mysql-test/t/fulltext_left_join.test +++ b/mysql-test/t/fulltext_left_join.test @@ -28,3 +28,15 @@ select match(t1.texte,t1.sujet,t1.motsclefs) against('droit' IN BOOLEAN MODE) drop table t1, t2; +# +# Bug #484, reported by Stephen Brandon +# + +create table t1 (venue_id int(11) default null, venue_text varchar(255) default null, dt datetime default null) type=myisam; +insert into t1 (venue_id, venue_text, dt) values (1, 'a1', '2003-05-23 19:30:00'),(null, 'a2', '2003-05-23 19:30:00'); +create table t2 (name varchar(255) not null default '', entity_id int(11) not null auto_increment, primary key (entity_id), fulltext key name (name)) type=myisam; +insert into t2 (name, entity_id) values ('aberdeen town hall', 1), ('glasgow royal concert hall', 2), ('queen\'s hall, edinburgh', 3); +select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen' in boolean mode) and dt = '2003-05-23 19:30:00'; +select * from t1 left join t2 on venue_id = entity_id where match(name) against('aberdeen') and dt = '2003-05-23 19:30:00'; +drop table t1,t2; + diff --git a/sql/item_func.cc b/sql/item_func.cc index 532a7cedec0..e847b203006 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2299,6 +2299,9 @@ double Item_func_match::val() if (ft_handler == NULL) DBUG_RETURN(-1.0); + if (table->null_row) /* NULL row from an outer join */ + return 0.0; + if (join_key) { if (table->file->ft_handler) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index ff6fde1ca0c..0e8b191e4ef 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1688,6 +1688,9 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, if (!cond_func || cond_func->key == NO_SUCH_KEY) return; + if (!(usable_tables & cond_func->table->map)) + return; + KEYUSE keyuse; keyuse.table= cond_func->table; From 85b11035b74802dbd6ad2f7ecbd60004c2ae1dd8 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Mon, 16 Jun 2003 23:38:33 +0200 Subject: [PATCH 034/237] Do not use 'created' for time anymore in Start_log_event, it's the same as the already-stored timestamp. Now 'created' is used only to know if this is a first binlog or not. And we may re-use the superfluous bytes in 5.0 when we need room. --- sql/log_event.cc | 8 +++----- sql/log_event.h | 11 +++++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 62d6bef3a51..b89f3c151a7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -302,13 +302,11 @@ void Start_log_event::print(FILE* file, bool short_form, char* last_db) return; print_header(file); - fprintf(file, "\tStart: binlog v %d, server v %s", binlog_version, + fprintf(file, "\tStart: binlog v %d, server v %s created ", binlog_version, server_version); + print_timestamp(file); if (created) - { - fprintf(file, " created "); - print_timestamp(file, &created); - } + fprintf(file," at startup"); fputc('\n', file); fflush(file); } diff --git a/sql/log_event.h b/sql/log_event.h index bb1c9260e21..d3c74f7f7c2 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -335,6 +335,17 @@ public: by FLUSH LOGS or automatic rotation), 'created' should be 0. This "trick" is used by MySQL >=4.0.14 slaves to know if they must drop the stale temporary tables or not. + Note that when 'created'!=0, it is always equal to the event's timestamp; + indeed Start_log_event is written only in log.cc where the first + constructor below is called, in which 'created' is set to 'when'. + So in fact 'created' is a useless variable. When it is 0 + we can read the actual value from timestamp ('when') and when it is + non-zero we can read the same value from timestamp ('when'). Conclusion: + - we use timestamp to print when the binlog was created. + - we use 'created' only to know if this is a first binlog or not. + In 3.23.57 we did not pay attention to this identity, so mysqlbinlog in + 3.23.57 does not print 'created the_date' if created was zero. This is now + fixed. */ time_t created; uint16 binlog_version; From 5a414bda8e50a83df4fde2c6966251578cdcfc7c Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Tue, 17 Jun 2003 16:20:07 +0300 Subject: [PATCH 035/237] Two Sprint tasks and two behaviour changes. --- sql/sql_acl.cc | 13 ++++++++---- sql/sql_parse.cc | 17 +++++++++------- sql/sql_union.cc | 12 +++++------ sql/sql_yacc.yy | 52 ++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 66 insertions(+), 28 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 12ea3a94464..e2946022ddf 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2038,7 +2038,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, check->column.c_ptr(), table_list->alias); DBUG_RETURN(-1); } - column_priv |= check->rights | (rights & COL_ACLS); + column_priv |= check->rights & COL_ACLS; } close_thread_tables(thd); } @@ -2173,7 +2173,12 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } else { - column_priv|= grant_table->cols; + /* + This code makes sure that if there is X privilege on the entire table and + X can be also a column privilege, that granting column privilege does not + revoke a table privilege. + */ + column_priv&= ~(grant_table->privs & ~grant_table->cols); } @@ -2186,13 +2191,13 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { // Crashend table ?? result= -1; /* purecov: deadcode */ } - else if (tables[2].table) + else if (tables[2].table && (column_priv | revoke_grant)) { if ((replace_column_table(grant_table,tables[2].table, *Str, columns, table_list->db, table_list->real_name, - rights, revoke_grant))) + (revoke_grant) ? rights : column_priv, revoke_grant))) { result= -1; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2f9a7db5ef4..392b4ae4235 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1959,11 +1959,6 @@ mysql_execute_command(void) if (thd->select_limit < select_lex->select_limit) thd->select_limit= HA_POS_ERROR; // No limit - if (check_dup(tables->db, tables->real_name, tables->next)) - { - net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name); - DBUG_VOID_RETURN; - } { /* TODO: Delete the following loop when locks is set by sql_yacc */ TABLE_LIST *table; @@ -3361,8 +3356,16 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, { if (!strcmp(alias_str,tables->alias) && !strcmp(ptr->db, tables->db)) { - net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */ - DBUG_RETURN(0); /* purecov: tested */ + if ((thd->lex.sql_command & (SQLCOM_INSERT_SELECT | SQLCOM_REPLACE_SELECT)) + && (tables->lock_type & (TL_WRITE_CONCURRENT_INSERT | + TL_WRITE_LOW_PRIORITY | TL_WRITE_DELAYED | + TL_WRITE))) + thd->lex.select->options |= OPTION_BUFFER_RESULT; + else + { + net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */ + DBUG_RETURN(0); /* purecov: tested */ + } } } } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 55b5d57d07d..407bf64d628 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -63,10 +63,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) */ lex_sl= sl; order= (ORDER *) lex_sl->order_list.first; - found_rows_for_union = (lex->select_lex.options & OPTION_FOUND_ROWS && - !describe && sl->select_limit); - if (found_rows_for_union) - lex->select_lex.options ^= OPTION_FOUND_ROWS; + found_rows_for_union = lex->select_lex.options & OPTION_FOUND_ROWS && sl->select_limit; // This is done to eliminate unnecessary slowing down of the first query if (!order || !describe) last_sl->next=0; // Remove this extra element @@ -144,7 +141,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) thd->select_limit=sl->select_limit+sl->offset_limit; if (thd->select_limit < sl->select_limit) thd->select_limit= HA_POS_ERROR; // no limit - if (thd->select_limit == HA_POS_ERROR) + if (thd->select_limit == HA_POS_ERROR || sl->braces) sl->options&= ~OPTION_FOUND_ROWS; res=mysql_select(thd, (describe && sl->linkage==NOT_A_SELECT) ? @@ -203,9 +200,12 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) { thd->offset_limit= 0; thd->select_limit= thd->variables.select_limit; + if (found_rows_for_union && !describe) + thd->options|= OPTION_FOUND_ROWS; } if (describe) thd->select_limit= HA_POS_ERROR; // no limit + res=mysql_select(thd,&result_table_list, item_list, NULL, (describe) ? 0 : order, (ORDER*) NULL, NULL, (ORDER*) NULL, @@ -264,7 +264,7 @@ bool select_union::send_data(List &values) if ((write_record(table,&info))) { if (create_myisam_from_heap(thd, table, tmp_table_param, info.last_errno, - 0)) + 1)) return 1; } return 0; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c79750c8014..c011c058dc8 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -595,7 +595,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild opt_union union_list - precision union_option opt_and + precision union_option END_OF_INPUT %type @@ -787,17 +787,31 @@ create: create2: '(' field_list ')' opt_create_table_options create3 {} - | opt_create_table_options create3 {}; + | opt_create_table_options create3 {} + | select_for_create {} + ; create3: /* empty */ {} - | opt_duplicate opt_as SELECT_SYM + | opt_duplicate opt_as select_for_create {} + ; + +select_for_create: + SELECT_SYM { LEX *lex=Lex; lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; mysql_init_select(lex); } - select_options select_item_list opt_select_from opt_union {}; + select_options select_item_list opt_select_from { Select->braces= 0;} opt_union + |'(' SELECT_SYM + { + LEX *lex=Lex; + lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; + mysql_init_select(lex); + } + select_options select_item_list opt_select_from ')' { Select->braces= 1;} union_opt + ; opt_as: /* empty */ {} @@ -2600,7 +2614,9 @@ insert_field_spec: lex->many_values.push_back(lex->insert_list)) YYABORT; } - ident_eq_list; + ident_eq_list + | select_for_insert {} + ; opt_field_spec: /* empty */ { } @@ -2609,20 +2625,34 @@ opt_field_spec: fields: fields ',' insert_ident { Lex->field_list.push_back($3); } - | insert_ident { Lex->field_list.push_back($1); }; + | insert_ident { Lex->field_list.push_back($1); } + ; insert_values: VALUES values_list {} - | SELECT_SYM - { + | select_for_insert {} + ; + +select_for_insert: + SELECT_SYM + { LEX *lex=Lex; lex->sql_command = (lex->sql_command == SQLCOM_INSERT ? SQLCOM_INSERT_SELECT : SQLCOM_REPLACE_SELECT); lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; mysql_init_select(lex); - } - select_options select_item_list select_from select_lock_type - opt_union {}; + } + select_options select_item_list opt_select_from select_lock_type { Select->braces= 0;} opt_union + |'(' SELECT_SYM + { + LEX *lex=Lex; + lex->sql_command = (lex->sql_command == SQLCOM_INSERT ? + SQLCOM_INSERT_SELECT : SQLCOM_REPLACE_SELECT); + lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; + mysql_init_select(lex); + } + select_options select_item_list opt_select_from select_lock_type ')' { Select->braces= 1;} union_opt + ; values_list: values_list ',' no_braces From ab5479e6e2a434d91d07f9293b1ab056ffbea56b Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Tue, 17 Jun 2003 16:35:20 +0200 Subject: [PATCH 036/237] Better error reporting in mysql-test-run (don't hide the important message with 'head'). Test fix (this sync_with_master was nonsense). Now all tests pass in 4.0 in autobuild. --- mysql-test/mysql-test-run.sh | 4 +++- mysql-test/t/rpl_rotate_logs.test | 3 --- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 1d25a4d0e3d..55adc3d88fc 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -569,7 +569,9 @@ error () { } error_is () { - $CAT < $TIMEFILE | $SED -e 's/.* At line \(.*\)\: \(.*\)/ \>\> Error at line \1: \2<\ Date: Tue, 17 Jun 2003 23:19:38 +0200 Subject: [PATCH 037/237] Changed change_master() to use ER_MASTER_INFO (better display). --- mysql-test/r/rpl_rotate_logs.result | 2 +- mysql-test/t/rpl_rotate_logs.test | 10 ++++++++-- sql/slave.cc | 1 + sql/sql_repl.cc | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index 741c53fe52b..f49006e8e05 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -5,7 +5,7 @@ Could not initialize master info structure, check permisions on master.info slave start; Could not initialize master info structure, check permisions on master.info change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; -Could not initialize master info +Could not initialize master info structure, check permisions on master.info reset slave; change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; reset master; diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index 9f7f44d7c28..c4dc5de38da 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -16,14 +16,20 @@ system cat /dev/null > var/slave-data/master.info; system chmod 000 var/slave-data/master.info; connection slave; drop table if exists t1, t2, t3, t4; +# START SLAVE will fail because it can't read the file (mode 000) (system error 13) --error 1201 slave start; system chmod 600 var/slave-data/master.info; +# It will fail again because the file is empty so the slave cannot get valuable +# info about how to connect to the master from it (failure in +# 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 -# Will get error 13 on Unix systems becasue file is not readable -!eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; +# 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 eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; diff --git a/sql/slave.cc b/sql/slave.cc index dc9ce9715d8..6c29d1a98bc 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1644,6 +1644,7 @@ int show_master_info(THD* thd, MASTER_INFO* mi) if (mi->host[0]) { + DBUG_PRINT("info",("host is set: '%s'", mi->host)); String *packet= &thd->packet; packet->length(0); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index a651d8002fd..e3af076da1f 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -828,7 +828,7 @@ int change_master(THD* thd, MASTER_INFO* mi) // TODO: see if needs re-write if (init_master_info(mi, master_info_file, relay_log_info_file, 0)) { - send_error(&thd->net, 0, "Could not initialize master info"); + send_error(&thd->net, ER_MASTER_INFO); unlock_slave_threads(mi); DBUG_RETURN(1); } From 01eb3d1e6236ad999a7d322c71baee0c0e21482b Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 18 Jun 2003 02:18:19 +0300 Subject: [PATCH 038/237] row0vers.c, row0sel.c, row0ins.c: Fix bug: InnoDB could print that it cannot find a clustered index record if an update undo, purge, and a consistent read coincided, in rare cases it might also have returned a wrong row in a query --- innobase/row/row0ins.c | 25 ++++++------ innobase/row/row0sel.c | 89 +++++++++++++++++++++++++++++------------ innobase/row/row0vers.c | 28 +++++-------- 3 files changed, 88 insertions(+), 54 deletions(-) diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index 23da0b9b93c..d36e5a9761e 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -791,27 +791,28 @@ row_ins_foreign_check_on_constraint( mem_heap_free(tmp_heap); clust_rec = btr_pcur_get_rec(cascade->pcur); - } - if (!page_rec_is_user_rec(clust_rec)) { - fprintf(stderr, + if (btr_pcur_get_low_match(cascade->pcur) + < dict_index_get_n_unique(clust_index)) { + fprintf(stderr, "InnoDB: error in cascade of a foreign key op\n" "InnoDB: index %s table %s\n", index->name, index->table->name); - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: record %s\n", err_buf); + rec_sprintf(err_buf, 900, rec); + fprintf(stderr, "InnoDB: record %s\n", err_buf); - rec_sprintf(err_buf, 900, clust_rec); - fprintf(stderr, "InnoDB: clustered record %s\n", err_buf); - - fprintf(stderr, + rec_sprintf(err_buf, 900, clust_rec); + fprintf(stderr, "InnoDB: clustered record %s\n", + err_buf); + fprintf(stderr, "InnoDB: Make a detailed bug report and send it\n"); - fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); + fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); - err = DB_SUCCESS; + err = DB_SUCCESS; - goto nonstandard_exit_func; + goto nonstandard_exit_func; + } } /* Set an X-lock on the row to delete or update in the child table */ diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 114ebf870b0..afc01247347 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -609,7 +609,25 @@ row_sel_get_clust_rec( clust_rec = btr_pcur_get_rec(&(plan->clust_pcur)); - ut_ad(page_rec_is_user_rec(clust_rec)); + if (btr_pcur_get_low_match(&(plan->clust_pcur)) + < dict_index_get_n_unique(index)) { + + ut_a(rec_get_deleted_flag(rec)); + ut_a(node->read_view); + + /* In a rare case it is possible that no clust rec is found + for a delete-marked secondary index record: if in row0umod.c + in row_undo_mod_remove_clust_low() we have already removed + the clust rec, while purge is still cleaning and removing + secondary index records associated with earlier versions of + the clustered index record. In that case we know that the + clustered index record did not exist in the read view of + trx. */ + + clust_rec = NULL; + + goto func_exit; + } if (!node->read_view) { /* Try to place a lock on the index record */ @@ -672,6 +690,7 @@ row_sel_get_clust_rec( row_sel_fetch_columns(index, clust_rec, UT_LIST_GET_FIRST(plan->columns)); +func_exit: *out_rec = clust_rec; return(DB_SUCCESS); @@ -1253,6 +1272,8 @@ rec_loop: /* PHASE 3: Get previous version in a consistent read */ + cons_read_requires_clust_rec = FALSE; + if (consistent_read) { /* This is a non-locking consistent read: if necessary, fetch a previous version of the record */ @@ -2269,7 +2290,10 @@ row_sel_get_clust_rec_for_mysql( /* out: DB_SUCCESS or error code */ row_prebuilt_t* prebuilt,/* in: prebuilt struct in the handle */ dict_index_t* sec_index,/* in: secondary index where rec resides */ - rec_t* rec, /* in: record in a non-clustered index */ + rec_t* rec, /* in: record in a non-clustered index; if + this is a locking read, then rec is not + allowed to be delete-marked, and that would + not make sense either */ que_thr_t* thr, /* in: query thread */ rec_t** out_rec,/* out: clustered record or an old version of it, NULL if the old version did not exist @@ -2285,7 +2309,7 @@ row_sel_get_clust_rec_for_mysql( ulint err; trx_t* trx; char err_buf[1000]; - + *out_rec = NULL; row_build_row_ref_in_tuple(prebuilt->clust_ref, sec_index, rec); @@ -2298,26 +2322,43 @@ row_sel_get_clust_rec_for_mysql( clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur); - if (!page_rec_is_user_rec(clust_rec)) { - ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: error clustered record for sec rec not found\n" - "InnoDB: index %s table %s\n", sec_index->name, - sec_index->table->name); + if (btr_pcur_get_low_match(prebuilt->clust_pcur) + < dict_index_get_n_unique(clust_index)) { + + /* In a rare case it is possible that no clust rec is found + for a delete-marked secondary index record: if in row0umod.c + in row_undo_mod_remove_clust_low() we have already removed + the clust rec, while purge is still cleaning and removing + secondary index records associated with earlier versions of + the clustered index record. In that case we know that the + clustered index record did not exist in the read view of + trx. */ - rec_sprintf(err_buf, 900, rec); - fprintf(stderr, "InnoDB: sec index record %s\n", err_buf); + if (!rec_get_deleted_flag(rec) + || prebuilt->select_lock_type != LOCK_NONE) { - rec_sprintf(err_buf, 900, clust_rec); - fprintf(stderr, "InnoDB: clust index record %s\n", err_buf); + ut_print_timestamp(stderr); + fprintf(stderr, + " InnoDB: error clustered record for sec rec not found\n" + "InnoDB: index %s table %s\n", sec_index->name, + sec_index->table->name); - trx = thr_get_trx(thr); - trx_print(err_buf, trx); + rec_sprintf(err_buf, 900, rec); + fprintf(stderr, + "InnoDB: sec index record %s\n", err_buf); - fprintf(stderr, - "%s\nInnoDB: Make a detailed bug report and send it\n", - err_buf); - fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); + rec_sprintf(err_buf, 900, clust_rec); + fprintf(stderr, + "InnoDB: clust index record %s\n", err_buf); + + trx = thr_get_trx(thr); + trx_print(err_buf, trx); + + fprintf(stderr, + "%s\nInnoDB: Make a detailed bug report and send it\n", + err_buf); + fprintf(stderr, "InnoDB: to mysql@lists.mysql.com\n"); + } clust_rec = NULL; @@ -2989,8 +3030,6 @@ rec_loop: /*-------------------------------------------------------------*/ /* PHASE 4: Look for matching records in a loop */ - cons_read_requires_clust_rec = FALSE; - rec = btr_pcur_get_rec(pcur); /* printf("Using index %s cnt %lu ", index->name, cnt); @@ -3145,6 +3184,8 @@ rec_loop: /* We are ready to look at a possible new index entry in the result set: the cursor is now placed on a user record */ + cons_read_requires_clust_rec = FALSE; + if (prebuilt->select_lock_type != LOCK_NONE) { /* Try to place a lock on the index record; note that delete marked records are a special case in a unique search. If there @@ -3170,8 +3211,6 @@ rec_loop: /* This is a non-locking consistent read: if necessary, fetch a previous version of the record */ - cons_read_requires_clust_rec = FALSE; - if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) { /* Do nothing: we let a non-locking SELECT read the @@ -3215,7 +3254,7 @@ rec_loop: if (rec_get_deleted_flag(rec) && !cons_read_requires_clust_rec) { - /* The record is delete marked: we can skip it if this is + /* The record is delete-marked: we can skip it if this is not a consistent read which might see an earlier version of a non-clustered index record */ @@ -3324,7 +3363,7 @@ got_row: goto normal_return; next_rec: - /*-------------------------------------------------------------*/ + /*-------------------------------------------------------------*/ /* PHASE 5: Move the cursor to the next index record */ if (mtr_has_extra_clust_latch) { diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c index 91aaba40812..5395f5160e4 100644 --- a/innobase/row/row0vers.c +++ b/innobase/row/row0vers.c @@ -59,7 +59,6 @@ row_vers_impl_x_locked_off_kernel( ibool rec_del; ulint err; mtr_t mtr; - char err_buf[1000]; ut_ad(mutex_own(&kernel_mutex)); ut_ad(!rw_lock_own(&(purge_sys->latch), RW_LOCK_SHARED)); @@ -77,22 +76,17 @@ row_vers_impl_x_locked_off_kernel( clust_rec = row_get_clust_rec(BTR_SEARCH_LEAF, rec, index, &clust_index, &mtr); if (!clust_rec) { - rec_sprintf(err_buf, 900, rec); - - ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: Error: cannot find the clustered index record\n" -"InnoDB: for a secondary index record in table %s index %s.\n" -"InnoDB: Secondary index record %s.\n" -"InnoDB: The table is probably corrupt. Please run CHECK TABLE on it.\n" -"InnoDB: You can try to repair the table by dump + drop + reimport.\n" -"InnoDB: Send a detailed bug report to mysql@lists.mysql.com.\n", - index->table_name, index->name, err_buf); - mutex_enter(&kernel_mutex); - mtr_commit(&mtr); - - /* We assume there is no lock on the record, though this - is not certain because the table is apparently corrupt */ + /* In a rare case it is possible that no clust rec is found + for a secondary index record: if in row0umod.c + row_undo_mod_remove_clust_low() we have already removed the + clust rec, while purge is still cleaning and removing + secondary index records associated with earlier versions of + the clustered index record. In that case there cannot be + any implicit lock on the secondary index record, because + an active transaction which has modified the secondary index + record has also modified the clustered index record. And in + a rollback we always undo the modifications to secondary index + records before the clustered index record. */ return(NULL); } From d970e339dd2c2c0ecd4183970bf9729b274b2bb8 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 18 Jun 2003 03:38:09 +0300 Subject: [PATCH 039/237] row0sel.c, row0ins.c: Fix error in previous push --- innobase/row/row0ins.c | 6 ++++-- innobase/row/row0sel.c | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c index d36e5a9761e..e02859bc851 100644 --- a/innobase/row/row0ins.c +++ b/innobase/row/row0ins.c @@ -792,8 +792,10 @@ row_ins_foreign_check_on_constraint( clust_rec = btr_pcur_get_rec(cascade->pcur); - if (btr_pcur_get_low_match(cascade->pcur) - < dict_index_get_n_unique(clust_index)) { + if (!page_rec_is_user_rec(clust_rec) + || btr_pcur_get_low_match(cascade->pcur) + < dict_index_get_n_unique(clust_index)) { + fprintf(stderr, "InnoDB: error in cascade of a foreign key op\n" "InnoDB: index %s table %s\n", index->name, diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index afc01247347..a263de74e3e 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -609,8 +609,12 @@ row_sel_get_clust_rec( clust_rec = btr_pcur_get_rec(&(plan->clust_pcur)); - if (btr_pcur_get_low_match(&(plan->clust_pcur)) - < dict_index_get_n_unique(index)) { + /* Note: only if the search ends up on a non-infimum record is the + low_match value the real match to the search tuple */ + + if (!page_rec_is_user_rec(clust_rec) + || btr_pcur_get_low_match(&(plan->clust_pcur)) + < dict_index_get_n_unique(index)) { ut_a(rec_get_deleted_flag(rec)); ut_a(node->read_view); @@ -2322,8 +2326,12 @@ row_sel_get_clust_rec_for_mysql( clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur); - if (btr_pcur_get_low_match(prebuilt->clust_pcur) - < dict_index_get_n_unique(clust_index)) { + /* Note: only if the search ends up on a non-infimum record is the + low_match value the real match to the search tuple */ + + if (!page_rec_is_user_rec(clust_rec) + || btr_pcur_get_low_match(prebuilt->clust_pcur) + < dict_index_get_n_unique(clust_index)) { /* In a rare case it is possible that no clust rec is found for a delete-marked secondary index record: if in row0umod.c From 6d4fe0280fa66c635a9328267567e6307049433e Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 18 Jun 2003 03:49:34 +0300 Subject: [PATCH 040/237] row0vers.c: Add forgotten mtr_commit() --- innobase/row/row0vers.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c index 5395f5160e4..1e9cef4c726 100644 --- a/innobase/row/row0vers.c +++ b/innobase/row/row0vers.c @@ -88,6 +88,8 @@ row_vers_impl_x_locked_off_kernel( a rollback we always undo the modifications to secondary index records before the clustered index record. */ + mtr_commit(&mtr); + return(NULL); } From b8cc47797a4d8ae8c129e372fe5bd0789f8b5441 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 18 Jun 2003 03:53:18 +0300 Subject: [PATCH 041/237] row0vers.c: Add forgotten mutex_enter() --- innobase/row/row0vers.c | 1 + 1 file changed, 1 insertion(+) diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c index 1e9cef4c726..d4a463d8a96 100644 --- a/innobase/row/row0vers.c +++ b/innobase/row/row0vers.c @@ -88,6 +88,7 @@ row_vers_impl_x_locked_off_kernel( a rollback we always undo the modifications to secondary index records before the clustered index record. */ + mutex_enter(&kernel_mutex); mtr_commit(&mtr); return(NULL); From b8ad5dea56e4ddf612668d636d6cef57ef5efdcb Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 18 Jun 2003 04:05:10 +0300 Subject: [PATCH 042/237] row0vers.c, row0sel.c: Backport the clust rec bug fix from 4.0 --- innobase/row/row0sel.c | 23 +++++++++++++++++++++-- innobase/row/row0vers.c | 14 -------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index c9de502eb9a..b06476219c6 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -598,7 +598,14 @@ row_sel_get_clust_rec( clust_rec = btr_pcur_get_rec(&(plan->clust_pcur)); - ut_ad(page_rec_is_user_rec(clust_rec)); + if (!page_rec_is_user_rec(clust_rec) + || btr_pcur_get_low_match(&(plan->clust_pcur)) + < dict_index_get_n_unique(index)) { + + clust_rec = NULL; + + goto func_exit; + } if (!node->read_view) { /* Try to place a lock on the index record */ @@ -661,6 +668,7 @@ row_sel_get_clust_rec( row_sel_fetch_columns(index, clust_rec, UT_LIST_GET_FIRST(plan->columns)); +func_exit: *out_rec = clust_rec; return(DB_SUCCESS); @@ -2206,7 +2214,17 @@ row_sel_get_clust_rec_for_mysql( clust_rec = btr_pcur_get_rec(prebuilt->clust_pcur); - ut_ad(page_rec_is_user_rec(clust_rec)); + /* Note: only if the search ends up on a non-infimum record is the + low_match value the real match to the search tuple */ + + if (!page_rec_is_user_rec(clust_rec) + || btr_pcur_get_low_match(prebuilt->clust_pcur) + < dict_index_get_n_unique(clust_index)) { + + clust_rec = NULL; + + goto func_exit; + } if (prebuilt->select_lock_type != LOCK_NONE) { /* Try to place a lock on the index record */ @@ -2268,6 +2286,7 @@ row_sel_get_clust_rec_for_mysql( } } +func_exit: *out_rec = clust_rec; if (prebuilt->select_lock_type == LOCK_X) { diff --git a/innobase/row/row0vers.c b/innobase/row/row0vers.c index cd8b18e5e12..baef6bca4ea 100644 --- a/innobase/row/row0vers.c +++ b/innobase/row/row0vers.c @@ -76,23 +76,9 @@ row_vers_impl_x_locked_off_kernel( clust_rec = row_get_clust_rec(BTR_SEARCH_LEAF, rec, index, &clust_index, &mtr); if (!clust_rec) { - rec_sprintf(err_buf, 900, rec); - - ut_print_timestamp(stderr); - fprintf(stderr, -" InnoDB: Error: cannot find the clustered index record\n" -"InnoDB: for a secondary index record in table %s index %s.\n" -"InnoDB: Secondary index record %s.\n" -"InnoDB: The table is probably corrupt. Please run CHECK TABLE on it.\n" -"InnoDB: You can try to repair the table by dump + drop + reimport.\n" -"InnoDB: Send a detailed bug report to mysql@lists.mysql.com.\n", - index->table_name, index->name, err_buf); mutex_enter(&kernel_mutex); mtr_commit(&mtr); - /* We assume there is no lock on the record, though this - is not certain because the table is apparently corrupt */ - return(NULL); } From b9b2b7dd27441b7e2541bdfa93fe058f53e70925 Mon Sep 17 00:00:00 2001 From: "miguel@hegel.(none)" <> Date: Wed, 18 Jun 2003 15:50:33 -0400 Subject: [PATCH 043/237] InstallShield Files requested by Greg --- BitKeeper/etc/logging_ok | 1 + .../3.23.XX-gpl/Component Definitions/.fgl | 37 + .../Component Definitions/Default.cdf | 192 ++++++ .../Component Definitions/Default.fgl | 42 ++ .../File Groups/Clients and Tools.fgl | 35 + .../3.23.XX-gpl/File Groups/Default.fdf | 82 +++ .../3.23.XX-gpl/File Groups/Default.fgl | 4 + .../3.23.XX-gpl/File Groups/Development.fgl | 191 ++++++ .../3.23.XX-gpl/File Groups/Documentation.fgl | 99 +++ .../3.23.XX-gpl/File Groups/Grant Tables.fgl | 36 + .../3.23.XX-gpl/File Groups/Servers.fgl | 184 +++++ .../3.23.XX-gpl/MySQL 3.23.XX-GPL.ipr | 51 ++ .../3.23.XX-gpl/Registry Entries/Default.rge | 4 + .../3.23.XX-gpl/Script Files/Setup.dbg | Bin 0 -> 28458 bytes .../3.23.XX-gpl/Script Files/Setup.ino | Bin 0 -> 58611 bytes .../3.23.XX-gpl/Script Files/Setup.ins | Bin 0 -> 57122 bytes .../3.23.XX-gpl/Script Files/Setup.obs | Bin 0 -> 65611 bytes .../3.23.XX-gpl/Script Files/Setup.rul | 641 ++++++++++++++++++ .../OS Independent/infolist.txt | 24 + .../OS Independent/SETUP.BMP | Bin 0 -> 15694 bytes .../3.23.XX-gpl/Shell Objects/Default.shl | 12 + .../String Tables/0009-English/value.shl | 23 + .../3.23.XX-gpl/String Tables/Default.shl | 74 ++ .../3.23.XX-gpl/Text Substitutions/Build.tsb | 56 ++ .../3.23.XX-gpl/Text Substitutions/Setup.tsb | 76 +++ .../3.23.XXcom/Component Definitions/.fgl | 37 + .../Component Definitions/Default.cdf | 192 ++++++ .../Component Definitions/Default.fgl | 42 ++ .../File Groups/Clients and Tools.fgl | 35 + .../3.23.XXcom/File Groups/Default.fdf | 82 +++ .../3.23.XXcom/File Groups/Default.fgl | 4 + .../3.23.XXcom/File Groups/Development.fgl | 190 ++++++ .../3.23.XXcom/File Groups/Documentation.fgl | 98 +++ .../3.23.XXcom/File Groups/Grant Tables.fgl | 36 + .../3.23.XXcom/File Groups/Servers.fgl | 183 +++++ .../3.23.XXcom/MySQL 3.23.com.ipr | 51 ++ .../3.23.XXcom/Registry Entries/Default.rge | 4 + .../3.23.XXcom/Script Files/Setup.dbg | Bin 0 -> 28458 bytes .../3.23.XXcom/Script Files/Setup.ino | Bin 0 -> 58611 bytes .../3.23.XXcom/Script Files/Setup.ins | Bin 0 -> 57122 bytes .../3.23.XXcom/Script Files/Setup.obs | Bin 0 -> 65611 bytes .../3.23.XXcom/Script Files/Setup.rul | 641 ++++++++++++++++++ .../OS Independent/infolist.txt | 24 + .../OS Independent/SETUP.BMP | Bin 0 -> 15694 bytes .../3.23.XXcom/Shell Objects/Default.shl | 12 + .../String Tables/0009-English/value.shl | 23 + .../3.23.XXcom/String Tables/Default.shl | 74 ++ .../3.23.XXcom/Text Substitutions/Build.tsb | 56 ++ .../3.23.XXcom/Text Substitutions/Setup.tsb | 76 +++ 49 files changed, 3724 insertions(+) create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/.fgl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.cdf create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.fgl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/File Groups/Clients and Tools.fgl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fdf create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fgl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/File Groups/Development.fgl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/File Groups/Documentation.fgl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/File Groups/Grant Tables.fgl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/File Groups/Servers.fgl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/MySQL 3.23.XX-GPL.ipr create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Registry Entries/Default.rge create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.dbg create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ino create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ins create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.obs create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.rul create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Shell Objects/Default.shl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/String Tables/0009-English/value.shl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/String Tables/Default.shl create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Build.tsb create mode 100644 VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Setup.tsb create mode 100644 VC++Files/InstallShield/3.23.XXcom/Component Definitions/.fgl create mode 100644 VC++Files/InstallShield/3.23.XXcom/Component Definitions/Default.cdf create mode 100644 VC++Files/InstallShield/3.23.XXcom/Component Definitions/Default.fgl create mode 100644 VC++Files/InstallShield/3.23.XXcom/File Groups/Clients and Tools.fgl create mode 100644 VC++Files/InstallShield/3.23.XXcom/File Groups/Default.fdf create mode 100644 VC++Files/InstallShield/3.23.XXcom/File Groups/Default.fgl create mode 100644 VC++Files/InstallShield/3.23.XXcom/File Groups/Development.fgl create mode 100644 VC++Files/InstallShield/3.23.XXcom/File Groups/Documentation.fgl create mode 100644 VC++Files/InstallShield/3.23.XXcom/File Groups/Grant Tables.fgl create mode 100644 VC++Files/InstallShield/3.23.XXcom/File Groups/Servers.fgl create mode 100644 VC++Files/InstallShield/3.23.XXcom/MySQL 3.23.com.ipr create mode 100644 VC++Files/InstallShield/3.23.XXcom/Registry Entries/Default.rge create mode 100644 VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.dbg create mode 100644 VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.ino create mode 100644 VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.ins create mode 100644 VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.obs create mode 100644 VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.rul create mode 100644 VC++Files/InstallShield/3.23.XXcom/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt create mode 100644 VC++Files/InstallShield/3.23.XXcom/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP create mode 100644 VC++Files/InstallShield/3.23.XXcom/Shell Objects/Default.shl create mode 100644 VC++Files/InstallShield/3.23.XXcom/String Tables/0009-English/value.shl create mode 100644 VC++Files/InstallShield/3.23.XXcom/String Tables/Default.shl create mode 100644 VC++Files/InstallShield/3.23.XXcom/Text Substitutions/Build.tsb create mode 100644 VC++Files/InstallShield/3.23.XXcom/Text Substitutions/Setup.tsb diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 2d9cd004d0f..767dcab7c8a 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -11,6 +11,7 @@ heikki@hundin.mysql.fi jani@hynda.mysql.fi jorge@linux.jorge.mysql.com lenz@mysql.com +miguel@hegel.(none) miguel@hegel.br miguel@hegel.local miguel@light.local diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/.fgl b/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/.fgl new file mode 100644 index 00000000000..81e474f9be8 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/.fgl @@ -0,0 +1,37 @@ +[General] +Type=FILELIST +Version=1.00.000 + +[topdir] +subdir0= +subdir1= +subdir2= +subdir3=USERDEFINED + +[] +DISPLAYTEXT=Windows Operating System +TYPE=TEXTSUBFIXED +subdir0=\ + +[\] +DISPLAYTEXT=Windows System Folder +TYPE=TEXTSUBFIXED + +[] +DISPLAYTEXT=Program Files Folder +TYPE=TEXTSUBFIXED +subdir0=\ + +[\] +DISPLAYTEXT=Common Files Folder +TYPE=TEXTSUBFIXED + +[] +DISPLAYTEXT=General Application Destination +TYPE=TEXTSUBFIXED + +[USERDEFINED] +DISPLAYTEXT=Script-defined Folders +TYPE=USERSTART + + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.cdf b/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.cdf new file mode 100644 index 00000000000..48d37800cd1 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.cdf @@ -0,0 +1,192 @@ +[Development] +required0=Servers +SELECTED=Yes +FILENEED=STANDARD +required1=Grant Tables +HTTPLOCATION= +STATUS=Examples, Libraries, Includes and Script files +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=Examples, Libraries, Includes and Script files +DISPLAYTEXT=Examples, Libraries, Includes and Script files +IMAGE= +DEFSELECTION=Yes +filegroup0=Development +COMMENT= +INCLUDEINBUILD=Yes +INSTALLATION=ALWAYSOVERWRITE +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + +[Grant Tables] +required0=Servers +SELECTED=Yes +FILENEED=CRITICAL +HTTPLOCATION= +STATUS=The Grant Tables and Core Files +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=The Grant Tables and Core Files +DISPLAYTEXT=The Grant Tables and Core Files +IMAGE= +DEFSELECTION=Yes +filegroup0=Grant Tables +requiredby0=Development +COMMENT= +INCLUDEINBUILD=Yes +requiredby1=Clients and Tools +INSTALLATION=NEVEROVERWRITE +requiredby2=Documentation +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + +[Components] +component0=Development +component1=Grant Tables +component2=Servers +component3=Clients and Tools +component4=Documentation + +[TopComponents] +component0=Servers +component1=Clients and Tools +component2=Documentation +component3=Development +component4=Grant Tables + +[SetupType] +setuptype0=Compact +setuptype1=Typical +setuptype2=Custom + +[Clients and Tools] +required0=Servers +SELECTED=Yes +FILENEED=HIGHLYRECOMMENDED +required1=Grant Tables +HTTPLOCATION= +STATUS=The MySQL clients and Maintenance Tools +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=The MySQL clients and Maintenance Tools +DISPLAYTEXT=The MySQL clients and Maintenance Tools +IMAGE= +DEFSELECTION=Yes +filegroup0=Clients and Tools +COMMENT= +INCLUDEINBUILD=Yes +INSTALLATION=NEWERDATE +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + +[Servers] +SELECTED=Yes +FILENEED=CRITICAL +HTTPLOCATION= +STATUS=The MySQL Servers +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=The MySQL Servers +DISPLAYTEXT=The MySQL Servers +IMAGE= +DEFSELECTION=Yes +filegroup0=Servers +requiredby0=Development +COMMENT= +INCLUDEINBUILD=Yes +requiredby1=Grant Tables +INSTALLATION=ALWAYSOVERWRITE +requiredby2=Clients and Tools +requiredby3=Documentation +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + +[SetupTypeItem-Compact] +Comment= +item0=Grant Tables +item1=Servers +item2=Clients and Tools +item3=Documentation +Descrip= +DisplayText= + +[SetupTypeItem-Custom] +Comment= +item0=Development +item1=Grant Tables +item2=Servers +item3=Clients and Tools +Descrip= +item4=Documentation +DisplayText= + +[Info] +Type=CompDef +Version=1.00.000 +Name= + +[SetupTypeItem-Typical] +Comment= +item0=Development +item1=Grant Tables +item2=Servers +item3=Clients and Tools +Descrip= +item4=Documentation +DisplayText= + +[Documentation] +required0=Servers +SELECTED=Yes +FILENEED=HIGHLYRECOMMENDED +required1=Grant Tables +HTTPLOCATION= +STATUS=The MySQL Documentation with different formats +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=The MySQL Documentation with different formats +DISPLAYTEXT=The MySQL Documentation with different formats +IMAGE= +DEFSELECTION=Yes +filegroup0=Documentation +COMMENT= +INCLUDEINBUILD=Yes +INSTALLATION=ALWAYSOVERWRITE +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.fgl b/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.fgl new file mode 100644 index 00000000000..4e20dcea4ab --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/Component Definitions/Default.fgl @@ -0,0 +1,42 @@ +[\] +DISPLAYTEXT=Common Files Folder +TYPE=TEXTSUBFIXED +fulldirectory= + +[\] +DISPLAYTEXT=Windows System Folder +TYPE=TEXTSUBFIXED +fulldirectory= + +[USERDEFINED] +DISPLAYTEXT=Script-defined Folders +TYPE=USERSTART +fulldirectory= + +[] +DISPLAYTEXT=Program Files Folder +SubDir0=\ +TYPE=TEXTSUBFIXED +fulldirectory= + +[] +DISPLAYTEXT=General Application Destination +TYPE=TEXTSUBFIXED +fulldirectory= + +[] +DISPLAYTEXT=Windows Operating System +SubDir0=\ +TYPE=TEXTSUBFIXED +fulldirectory= + +[TopDir] +SubDir0= +SubDir1= +SubDir2= +SubDir3=USERDEFINED + +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Clients and Tools.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Clients and Tools.fgl new file mode 100644 index 00000000000..7f30ff9f64b --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Clients and Tools.fgl @@ -0,0 +1,35 @@ +[bin] +file15=C:\mysql\bin\pack_isam.exe +file16=C:\mysql\bin\perror.exe +file0=C:\mysql\bin\isamchk.exe +file17=C:\mysql\bin\replace.exe +file1=C:\mysql\bin\myisamchk.exe +file18=C:\mysql\bin\winmysqladmin.cnt +file2=C:\mysql\bin\myisamlog.exe +file19=C:\mysql\bin\winmysqladmin.exe +file3=C:\mysql\bin\myisampack.exe +file4=C:\mysql\bin\mysql.exe +file5=C:\mysql\bin\mysqladmin.exe +file6=C:\mysql\bin\mysqlbinlog.exe +file7=C:\mysql\bin\mysqlc.exe +file8=C:\mysql\bin\mysqlcheck.exe +file9=C:\mysql\bin\mysqldump.exe +file20=C:\mysql\bin\WINMYSQLADMIN.HLP +file21=C:\mysql\bin\cygwinb19.dll +file10=C:\mysql\bin\mysqlimport.exe +fulldirectory= +file22=C:\mysql\bin\libmySQL.dll +file11=C:\mysql\bin\MySqlManager.exe +file23=C:\mysql\bin\my_print_defaults.exe +file12=C:\mysql\bin\mysqlshow.exe +file24=C:\mysql\bin\comp-err.exe +file13=C:\mysql\bin\mysqlshutdown.exe +file14=C:\mysql\bin\mysqlwatch.exe + +[TopDir] +SubDir0=bin + +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fdf b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fdf new file mode 100644 index 00000000000..8096a4b74bf --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fdf @@ -0,0 +1,82 @@ +[FileGroups] +group0=Development +group1=Grant Tables +group2=Servers +group3=Clients and Tools +group4=Documentation + +[Development] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM= +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + +[Grant Tables] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM= +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + +[Clients and Tools] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM=0000000000000000 +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + +[Servers] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM= +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + +[Info] +Type=FileGrp +Version=1.00.000 +Name= + +[Documentation] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM= +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fgl new file mode 100644 index 00000000000..94344a6ff69 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Default.fgl @@ -0,0 +1,4 @@ +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Development.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Development.fgl new file mode 100644 index 00000000000..e7b8cc7cd0f --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Development.fgl @@ -0,0 +1,191 @@ +[bench\Data\Wisconsin] +file0=C:\mysql\bench\Data\Wisconsin\onek.data +file1=C:\mysql\bench\Data\Wisconsin\tenk.data +fulldirectory= + +[lib\debug] +file0=C:\mysql\lib\debug\libmySQL.dll +file1=C:\mysql\lib\debug\libmySQL.lib +file2=C:\mysql\lib\debug\mysqlclient.lib +file3=C:\mysql\lib\debug\zlib.lib +fulldirectory= + +[bench\output] +fulldirectory= + +[examples\libmysqltest] +file0=C:\mysql\examples\libmysqltest\myTest.c +file1=C:\mysql\examples\libmysqltest\myTest.dsp +file2=C:\mysql\examples\libmysqltest\myTest.dsw +file3=C:\mysql\examples\libmysqltest\myTest.exe +file4=C:\mysql\examples\libmysqltest\myTest.mak +file5=C:\mysql\examples\libmysqltest\myTest.ncb +file6=C:\mysql\examples\libmysqltest\myTest.opt +file7=C:\mysql\examples\libmysqltest\readme +fulldirectory= + +[include] +file0=C:\mysql\include\raid.h +file1=C:\mysql\include\errmsg.h +file2=C:\mysql\include\Libmysql.def +file3=C:\mysql\include\m_ctype.h +file4=C:\mysql\include\m_string.h +file5=C:\mysql\include\my_list.h +file6=C:\mysql\include\my_pthread.h +file7=C:\mysql\include\my_sys.h +file8=C:\mysql\include\mysql.h +file9=C:\mysql\include\mysql_com.h +file10=C:\mysql\include\mysql_version.h +fulldirectory= +file11=C:\mysql\include\mysqld_error.h +file12=C:\mysql\include\dbug.h +file13=C:\mysql\include\my_global.h +file14=C:\mysql\include\config-win.h + +[examples] +SubDir0=examples\libmysqltest +SubDir1=examples\tests +fulldirectory= + +[lib\opt] +file0=C:\mysql\lib\opt\libmySQL.dll +file1=C:\mysql\lib\opt\libmySQL.lib +file2=C:\mysql\lib\opt\mysqlclient.lib +file3=C:\mysql\lib\opt\zlib.lib +fulldirectory= + +[bench\Data] +SubDir0=bench\Data\ATIS +SubDir1=bench\Data\Wisconsin +fulldirectory= + +[bench\limits] +file15=C:\mysql\bench\limits\pg.comment +file16=C:\mysql\bench\limits\solid.cfg +file0=C:\mysql\bench\limits\access.cfg +file17=C:\mysql\bench\limits\solid-nt4.cfg +file1=C:\mysql\bench\limits\access.comment +file18=C:\mysql\bench\limits\sybase.cfg +file2=C:\mysql\bench\limits\Adabas.cfg +file3=C:\mysql\bench\limits\Adabas.comment +file4=C:\mysql\bench\limits\Db2.cfg +file5=C:\mysql\bench\limits\empress.cfg +file6=C:\mysql\bench\limits\empress.comment +file7=C:\mysql\bench\limits\Informix.cfg +file8=C:\mysql\bench\limits\Informix.comment +file9=C:\mysql\bench\limits\msql.cfg +file10=C:\mysql\bench\limits\ms-sql.cfg +fulldirectory= +file11=C:\mysql\bench\limits\Ms-sql65.cfg +file12=C:\mysql\bench\limits\mysql.cfg +file13=C:\mysql\bench\limits\oracle.cfg +file14=C:\mysql\bench\limits\pg.cfg + +[TopDir] +SubDir0=bench +SubDir1=examples +SubDir2=include +SubDir3=lib +SubDir4=scripts + +[bench] +file15=C:\mysql\bench\test-create +file16=C:\mysql\bench\test-insert +file0=C:\mysql\bench\uname.bat +file17=C:\mysql\bench\test-select +file1=C:\mysql\bench\compare-results +file18=C:\mysql\bench\test-wisconsin +file2=C:\mysql\bench\copy-db +file19=C:\mysql\bench\bench-init.pl +file3=C:\mysql\bench\crash-me +file4=C:\mysql\bench\example.bat +file5=C:\mysql\bench\print-limit-table +file6=C:\mysql\bench\pwd.bat +file7=C:\mysql\bench\Readme +SubDir0=bench\Data +file8=C:\mysql\bench\run.bat +SubDir1=bench\limits +file9=C:\mysql\bench\run-all-tests +SubDir2=bench\output +file10=C:\mysql\bench\server-cfg +fulldirectory= +file11=C:\mysql\bench\test-alter-table +file12=C:\mysql\bench\test-ATIS +file13=C:\mysql\bench\test-big-tables +file14=C:\mysql\bench\test-connect + +[examples\tests] +file15=C:\mysql\examples\tests\lock_test.res +file16=C:\mysql\examples\tests\mail_to_db.pl +file0=C:\mysql\examples\tests\unique_users.tst +file17=C:\mysql\examples\tests\table_types.pl +file1=C:\mysql\examples\tests\auto_increment.tst +file18=C:\mysql\examples\tests\test_delayed_insert.pl +file2=C:\mysql\examples\tests\big_record.pl +file19=C:\mysql\examples\tests\udf_test +file3=C:\mysql\examples\tests\big_record.res +file4=C:\mysql\examples\tests\czech-sorting +file5=C:\mysql\examples\tests\deadlock-script.pl +file6=C:\mysql\examples\tests\export.pl +file7=C:\mysql\examples\tests\fork_test.pl +file8=C:\mysql\examples\tests\fork2_test.pl +file9=C:\mysql\examples\tests\fork3_test.pl +file20=C:\mysql\examples\tests\udf_test.res +file21=C:\mysql\examples\tests\auto_increment.res +file10=C:\mysql\examples\tests\function.res +fulldirectory= +file11=C:\mysql\examples\tests\function.tst +file12=C:\mysql\examples\tests\grant.pl +file13=C:\mysql\examples\tests\grant.res +file14=C:\mysql\examples\tests\lock_test.pl + +[bench\Data\ATIS] +file26=C:\mysql\bench\Data\ATIS\stop1.txt +file15=C:\mysql\bench\Data\ATIS\flight_class.txt +file27=C:\mysql\bench\Data\ATIS\time_interval.txt +file16=C:\mysql\bench\Data\ATIS\flight_day.txt +file0=C:\mysql\bench\Data\ATIS\transport.txt +file28=C:\mysql\bench\Data\ATIS\time_zone.txt +file17=C:\mysql\bench\Data\ATIS\flight_fare.txt +file1=C:\mysql\bench\Data\ATIS\airline.txt +file29=C:\mysql\bench\Data\ATIS\aircraft.txt +file18=C:\mysql\bench\Data\ATIS\food_service.txt +file2=C:\mysql\bench\Data\ATIS\airport.txt +file19=C:\mysql\bench\Data\ATIS\ground_service.txt +file3=C:\mysql\bench\Data\ATIS\airport_service.txt +file4=C:\mysql\bench\Data\ATIS\city.txt +file5=C:\mysql\bench\Data\ATIS\class_of_service.txt +file6=C:\mysql\bench\Data\ATIS\code_description.txt +file7=C:\mysql\bench\Data\ATIS\compound_class.txt +file8=C:\mysql\bench\Data\ATIS\connect_leg.txt +file9=C:\mysql\bench\Data\ATIS\date_day.txt +file20=C:\mysql\bench\Data\ATIS\month_name.txt +file21=C:\mysql\bench\Data\ATIS\restrict_carrier.txt +file10=C:\mysql\bench\Data\ATIS\day_name.txt +fulldirectory= +file22=C:\mysql\bench\Data\ATIS\restrict_class.txt +file11=C:\mysql\bench\Data\ATIS\dual_carrier.txt +file23=C:\mysql\bench\Data\ATIS\restriction.txt +file12=C:\mysql\bench\Data\ATIS\fare.txt +file24=C:\mysql\bench\Data\ATIS\state.txt +file13=C:\mysql\bench\Data\ATIS\fconnection.txt +file25=C:\mysql\bench\Data\ATIS\stop.txt +file14=C:\mysql\bench\Data\ATIS\flight.txt + +[General] +Type=FILELIST +Version=1.00.000 + +[scripts] +file0=C:\mysql\scripts\mysql_find_rows.pl +file1=C:\mysql\scripts\mysql_setpermission.pl +file2=C:\mysql\scripts\mysqlhotcopy.pl +file3=C:\mysql\scripts\Readme +fulldirectory= + +[lib] +file0=C:\mysql\lib\Readme +SubDir0=lib\debug +SubDir1=lib\opt +fulldirectory= + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Documentation.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Documentation.fgl new file mode 100644 index 00000000000..80fe777cf0f --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Documentation.fgl @@ -0,0 +1,99 @@ +[Docs\Flags] +file59=C:\mysql\Docs\Flags\romania.gif +file48=C:\mysql\Docs\Flags\kroatia.eps +file37=C:\mysql\Docs\Flags\iceland.gif +file26=C:\mysql\Docs\Flags\france.eps +file15=C:\mysql\Docs\Flags\china.gif +file49=C:\mysql\Docs\Flags\kroatia.gif +file38=C:\mysql\Docs\Flags\ireland.eps +file27=C:\mysql\Docs\Flags\france.gif +file16=C:\mysql\Docs\Flags\croatia.eps +file0=C:\mysql\Docs\Flags\usa.gif +file39=C:\mysql\Docs\Flags\ireland.gif +file28=C:\mysql\Docs\Flags\germany.eps +file17=C:\mysql\Docs\Flags\croatia.gif +file1=C:\mysql\Docs\Flags\argentina.gif +file29=C:\mysql\Docs\Flags\germany.gif +file18=C:\mysql\Docs\Flags\czech-republic.eps +file2=C:\mysql\Docs\Flags\australia.eps +file19=C:\mysql\Docs\Flags\czech-republic.gif +file3=C:\mysql\Docs\Flags\australia.gif +file80=C:\mysql\Docs\Flags\usa.eps +file4=C:\mysql\Docs\Flags\austria.eps +file81=C:\mysql\Docs\Flags\argentina.eps +file70=C:\mysql\Docs\Flags\spain.eps +file5=C:\mysql\Docs\Flags\austria.gif +file71=C:\mysql\Docs\Flags\spain.gif +file60=C:\mysql\Docs\Flags\russia.eps +file6=C:\mysql\Docs\Flags\brazil.eps +file72=C:\mysql\Docs\Flags\sweden.eps +file61=C:\mysql\Docs\Flags\russia.gif +file50=C:\mysql\Docs\Flags\latvia.eps +file7=C:\mysql\Docs\Flags\brazil.gif +file73=C:\mysql\Docs\Flags\sweden.gif +file62=C:\mysql\Docs\Flags\singapore.eps +file51=C:\mysql\Docs\Flags\latvia.gif +file40=C:\mysql\Docs\Flags\island.eps +file8=C:\mysql\Docs\Flags\bulgaria.eps +file74=C:\mysql\Docs\Flags\switzerland.eps +file63=C:\mysql\Docs\Flags\singapore.gif +file52=C:\mysql\Docs\Flags\netherlands.eps +file41=C:\mysql\Docs\Flags\island.gif +file30=C:\mysql\Docs\Flags\great-britain.eps +file9=C:\mysql\Docs\Flags\bulgaria.gif +file75=C:\mysql\Docs\Flags\switzerland.gif +file64=C:\mysql\Docs\Flags\south-africa.eps +file53=C:\mysql\Docs\Flags\netherlands.gif +file42=C:\mysql\Docs\Flags\israel.eps +file31=C:\mysql\Docs\Flags\great-britain.gif +file20=C:\mysql\Docs\Flags\denmark.eps +file76=C:\mysql\Docs\Flags\taiwan.eps +file65=C:\mysql\Docs\Flags\south-africa.gif +file54=C:\mysql\Docs\Flags\poland.eps +file43=C:\mysql\Docs\Flags\israel.gif +file32=C:\mysql\Docs\Flags\greece.eps +file21=C:\mysql\Docs\Flags\denmark.gif +file10=C:\mysql\Docs\Flags\canada.eps +fulldirectory= +file77=C:\mysql\Docs\Flags\taiwan.gif +file66=C:\mysql\Docs\Flags\south-africa1.eps +file55=C:\mysql\Docs\Flags\poland.gif +file44=C:\mysql\Docs\Flags\italy.eps +file33=C:\mysql\Docs\Flags\greece.gif +file22=C:\mysql\Docs\Flags\estonia.eps +file11=C:\mysql\Docs\Flags\canada.gif +file78=C:\mysql\Docs\Flags\ukraine.eps +file67=C:\mysql\Docs\Flags\south-africa1.gif +file56=C:\mysql\Docs\Flags\portugal.eps +file45=C:\mysql\Docs\Flags\italy.gif +file34=C:\mysql\Docs\Flags\hungary.eps +file23=C:\mysql\Docs\Flags\estonia.gif +file12=C:\mysql\Docs\Flags\chile.eps +file79=C:\mysql\Docs\Flags\ukraine.gif +file68=C:\mysql\Docs\Flags\south-korea.eps +file57=C:\mysql\Docs\Flags\portugal.gif +file46=C:\mysql\Docs\Flags\japan.eps +file35=C:\mysql\Docs\Flags\hungary.gif +file24=C:\mysql\Docs\Flags\finland.eps +file13=C:\mysql\Docs\Flags\chile.gif +file69=C:\mysql\Docs\Flags\south-korea.gif +file58=C:\mysql\Docs\Flags\romania.eps +file47=C:\mysql\Docs\Flags\japan.gif +file36=C:\mysql\Docs\Flags\iceland.eps +file25=C:\mysql\Docs\Flags\finland.gif +file14=C:\mysql\Docs\Flags\china.eps + +[Docs] +file0=C:\mysql\Docs\manual_toc.html +file1=C:\mysql\Docs\manual.html +file2=C:\mysql\Docs\manual.txt +SubDir0=Docs\Flags +fulldirectory= + +[TopDir] +SubDir0=Docs + +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Grant Tables.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Grant Tables.fgl new file mode 100644 index 00000000000..178065a7003 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Grant Tables.fgl @@ -0,0 +1,36 @@ +[data\test] +fulldirectory= + +[data\mysql] +file15=C:\mysql\data\mysql\func.frm +file16=C:\mysql\data\mysql\func.MYD +file0=C:\mysql\data\mysql\columns_priv.frm +file17=C:\mysql\data\mysql\func.MYI +file1=C:\mysql\data\mysql\columns_priv.MYD +file2=C:\mysql\data\mysql\columns_priv.MYI +file3=C:\mysql\data\mysql\db.frm +file4=C:\mysql\data\mysql\db.MYD +file5=C:\mysql\data\mysql\db.MYI +file6=C:\mysql\data\mysql\host.frm +file7=C:\mysql\data\mysql\host.MYD +file8=C:\mysql\data\mysql\host.MYI +file9=C:\mysql\data\mysql\tables_priv.frm +file10=C:\mysql\data\mysql\tables_priv.MYD +fulldirectory= +file11=C:\mysql\data\mysql\tables_priv.MYI +file12=C:\mysql\data\mysql\user.frm +file13=C:\mysql\data\mysql\user.MYD +file14=C:\mysql\data\mysql\user.MYI + +[TopDir] +SubDir0=data + +[data] +SubDir0=data\mysql +SubDir1=data\test +fulldirectory= + +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Servers.fgl b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Servers.fgl new file mode 100644 index 00000000000..b23e2f90595 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/File Groups/Servers.fgl @@ -0,0 +1,184 @@ +[share\polish] +file0=C:\mysql\share\polish\errmsg.sys +file1=C:\mysql\share\polish\errmsg.txt +fulldirectory= + +[share\dutch] +file0=C:\mysql\share\dutch\errmsg.sys +file1=C:\mysql\share\dutch\errmsg.txt +fulldirectory= + +[share\spanish] +file0=C:\mysql\share\spanish\errmsg.sys +file1=C:\mysql\share\spanish\errmsg.txt +fulldirectory= + +[share\english] +file0=C:\mysql\share\english\errmsg.sys +file1=C:\mysql\share\english\errmsg.txt +fulldirectory= + +[bin] +file0=C:\mysql\bin\mysqld-opt.exe +file1=C:\mysql\bin\mysqld-max.exe +file2=C:\mysql\bin\mysqld-max-nt.exe +file3=C:\mysql\bin\mysqld-nt.exe +file4=C:\mysql\bin\mysqld.exe +fulldirectory= + +[share\korean] +file0=C:\mysql\share\korean\errmsg.sys +file1=C:\mysql\share\korean\errmsg.txt +fulldirectory= + +[share\charsets] +file15=C:\mysql\share\charsets\latin1.conf +file16=C:\mysql\share\charsets\latin2.conf +file0=C:\mysql\share\charsets\win1251ukr.conf +file17=C:\mysql\share\charsets\latin5.conf +file1=C:\mysql\share\charsets\cp1257.conf +file18=C:\mysql\share\charsets\Readme +file2=C:\mysql\share\charsets\croat.conf +file19=C:\mysql\share\charsets\swe7.conf +file3=C:\mysql\share\charsets\danish.conf +file4=C:\mysql\share\charsets\dec8.conf +file5=C:\mysql\share\charsets\dos.conf +file6=C:\mysql\share\charsets\estonia.conf +file7=C:\mysql\share\charsets\german1.conf +file8=C:\mysql\share\charsets\greek.conf +file9=C:\mysql\share\charsets\hebrew.conf +file20=C:\mysql\share\charsets\usa7.conf +file21=C:\mysql\share\charsets\win1250.conf +file10=C:\mysql\share\charsets\hp8.conf +fulldirectory= +file22=C:\mysql\share\charsets\win1251.conf +file11=C:\mysql\share\charsets\hungarian.conf +file23=C:\mysql\share\charsets\cp1251.conf +file12=C:\mysql\share\charsets\Index +file13=C:\mysql\share\charsets\koi8_ru.conf +file14=C:\mysql\share\charsets\koi8_ukr.conf + +[share\ukrainian] +file0=C:\mysql\share\ukrainian\errmsg.sys +file1=C:\mysql\share\ukrainian\errmsg.txt +fulldirectory= + +[share\hungarian] +file0=C:\mysql\share\hungarian\errmsg.sys +file1=C:\mysql\share\hungarian\errmsg.txt +fulldirectory= + +[share\german] +file0=C:\mysql\share\german\errmsg.sys +file1=C:\mysql\share\german\errmsg.txt +fulldirectory= + +[share\portuguese] +file0=C:\mysql\share\portuguese\errmsg.sys +file1=C:\mysql\share\portuguese\errmsg.txt +fulldirectory= + +[share\estonian] +file0=C:\mysql\share\estonian\errmsg.sys +file1=C:\mysql\share\estonian\errmsg.txt +fulldirectory= + +[share\romanian] +file0=C:\mysql\share\romanian\errmsg.sys +file1=C:\mysql\share\romanian\errmsg.txt +fulldirectory= + +[share\french] +file0=C:\mysql\share\french\errmsg.sys +file1=C:\mysql\share\french\errmsg.txt +fulldirectory= + +[share\swedish] +file0=C:\mysql\share\swedish\errmsg.sys +file1=C:\mysql\share\swedish\errmsg.txt +fulldirectory= + +[share\slovak] +file0=C:\mysql\share\slovak\errmsg.sys +file1=C:\mysql\share\slovak\errmsg.txt +fulldirectory= + +[share\greek] +file0=C:\mysql\share\greek\errmsg.sys +file1=C:\mysql\share\greek\errmsg.txt +fulldirectory= + +[TopDir] +file0=C:\mysql\mysqlbug.txt +file1=C:\mysql\my-small.cnf +file2=C:\mysql\my-large.cnf +file3=C:\mysql\my-medium.cnf +file4=C:\mysql\my-huge.cnf +SubDir0=bin +SubDir1=share + +[share] +SubDir8=share\hungarian +SubDir9=share\charsets +SubDir20=share\spanish +SubDir21=share\swedish +SubDir10=share\italian +SubDir22=share\ukrainian +SubDir11=share\japanese +SubDir12=share\korean +SubDir13=share\norwegian +SubDir14=share\norwegian-ny +SubDir15=share\polish +SubDir16=share\portuguese +SubDir0=share\czech +SubDir17=share\romanian +SubDir1=share\danish +SubDir18=share\russian +SubDir2=share\dutch +SubDir19=share\slovak +SubDir3=share\english +fulldirectory= +SubDir4=share\estonian +SubDir5=share\french +SubDir6=share\german +SubDir7=share\greek + +[share\norwegian-ny] +file0=C:\mysql\share\norwegian-ny\errmsg.sys +file1=C:\mysql\share\norwegian-ny\errmsg.txt +fulldirectory= + +[share\danish] +file0=C:\mysql\share\danish\errmsg.sys +file1=C:\mysql\share\danish\errmsg.txt +fulldirectory= + +[share\czech] +file0=C:\mysql\share\czech\errmsg.sys +file1=C:\mysql\share\czech\errmsg.txt +fulldirectory= + +[General] +Type=FILELIST +Version=1.00.000 + +[share\russian] +file0=C:\mysql\share\russian\errmsg.sys +file1=C:\mysql\share\russian\errmsg.txt +fulldirectory= + +[share\norwegian] +file0=C:\mysql\share\norwegian\errmsg.sys +file1=C:\mysql\share\norwegian\errmsg.txt +fulldirectory= + +[share\japanese] +file0=C:\mysql\share\japanese\errmsg.sys +file1=C:\mysql\share\japanese\errmsg.txt +fulldirectory= + +[share\italian] +file0=C:\mysql\share\italian\errmsg.sys +file1=C:\mysql\share\italian\errmsg.txt +fulldirectory= + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/MySQL 3.23.XX-GPL.ipr b/VC++Files/InstallShield/3.23.XX-gpl/MySQL 3.23.XX-GPL.ipr new file mode 100644 index 00000000000..de15790e744 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/MySQL 3.23.XX-GPL.ipr @@ -0,0 +1,51 @@ +[Language] +LanguageSupport0=0009 + +[OperatingSystem] +OSSupport=0000000000010010 + +[Data] +CurrentMedia= +CurrentComponentDef=Default.cdf +ProductName=MySQL Servers and Clients +set_mifserial= +DevEnvironment=Microsoft Visual C++ 6 +AppExe= +set_dlldebug=No +EmailAddresss= +Instructions=Instructions.txt +set_testmode=No +set_mif=No +SummaryText= +Department= +HomeURL= +Author= +Type=Database Application +InstallRoot=C:\MySQL-Install\3.23.XX-gpl +Version=1.00.000 +InstallationGUID=40744a4d-efed-4cff-84a9-9e6389550f5c +set_level=Level 3 +CurrentFileGroupDef=Default.fdf +Notes=Notes.txt +set_maxerr=50 +set_args= +set_miffile=Status.mif +set_dllcmdline= +Copyright= +set_warnaserr=No +CurrentPlatform= +Category= +set_preproc= +CurrentLanguage=English +CompanyName=MySQL +Description=Description.txt +set_maxwarn=50 +set_crc=Yes +set_compileb4build=No + +[MediaInfo] + +[General] +Type=INSTALLMAIN +Version=1.10.000 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Registry Entries/Default.rge b/VC++Files/InstallShield/3.23.XX-gpl/Registry Entries/Default.rge new file mode 100644 index 00000000000..537dfd82e48 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/Registry Entries/Default.rge @@ -0,0 +1,4 @@ +[General] +Type=REGISTRYDATA +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.dbg b/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.dbg new file mode 100644 index 0000000000000000000000000000000000000000..0c6d4e6b70812d069322e88155868913fc543e33 GIT binary patch literal 28458 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 literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ino b/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ino new file mode 100644 index 0000000000000000000000000000000000000000..204d8ea0f364524a444de8aa4c839fbdfb40413c GIT binary patch literal 58611 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 z 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 literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ins b/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.ins new file mode 100644 index 0000000000000000000000000000000000000000..759009b5c8462f5f1b617fb9f202c2e638ce4bc4 GIT binary patch literal 57122 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 U?Y7{S!vK%H{K_l&d*#Ca2lRel4gdfE literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.obs b/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.obs new file mode 100644 index 0000000000000000000000000000000000000000..5fcfcb62c4e70338ce55aab3c89149f351d7f4c1 GIT binary patch literal 65611 zcmdsg34k3%wRUySa+3)pKnM~R8TNfgb|gbGgptW4%p`0t5QbzDMv_dJnXrinf=`hk z*;jocA}*jPCI~3Jr=oytt_bcv1w}znwg)Kp|GrbFmcHG0G81_Izkdi{PFHuGsycP* zoKs8pJ!$fb4_hzOLR2yJj5#R`yRare;lQ zOoFS!wlb#e`-jQJRlhLiLHz#^{=fBC#$5NbF+a!u{BwBSa5M7byKY8$tKV#~nfdGS z_rGXfIBuLVX}#IXY-=WM^TJgo`OWIfepj0gOUt5Cz9LV<_sh!W?$S(%pJhe*O5RO&a(X1m7Va{mh0A) zOO%v!RS^E#vIrkHBxBc5GnVm(CC=W|jB_?6<8Z4|6|LG8Dpk9)sjoNV7xwk{%oDX+ zLm7y2iQ4U%)R;Qt!{0S!mq9gjpht5Oa}7UlsP%snIcv;;=&7$!?J4Mv}!%Bc>YRcu|Myk|k zYHN(^ynRgFUeQ2UTb`JxF{y3za?7@KZFzUd6HM_0P%>~df_BXt?V2~CrDIBKlb5$V z%g({G1szw1O1eMfxVi1Zevl#$w1XlTMtg^U*{5PM4+ou4189b3@vcZ}7OpN~Rkxv@ zR)}?j`8R`sEcuzuX%W(_4p{>uw%}o~6Va_Lqe!9FcxpANz41g{ZX|(iMz*dDsfrj2 z7P5`$OX^rjid2*bb#Rg#sl7UB@~O=enx-~EuXbaTR#C(1Q`6Ako*bo5QpG2?HMdQz zT^T)^xu{P}W8i{f!v${TIG)(j+B~s+GW2P%9M@Fg*r0VJ$3ZZ|a6mi5h}*(UZJFBI zJY#&*l&KhtCp5M5KE_U|2AV?}BW7J$bY*X=1Wx2gPQ*CWM> zYJgPenW({TAlD`d)h-NAm&NN1RWHi0W>6Wl4ksgTFpqm@>qDp29o?=mlfhf6S}>Nt z34gRAYeC8YIRS(d5ATP<_OW`sgQ*{8#veU>-X(n(%=Ido6x=M?H0a_E-cW4jO`;gs zb>$6aJ6bg|q&&Q%BenqHRJ=j^e^OIR8*L@*JpL(di$_YZ z8~(WhJqb_aVF(T7N;!IYwoHoL;s zXe2@@#f3=~krl~VnU6qJ2~I1ka^i>(P9*A9+rfl}qeeFC6rWWJL5tPrgIcZC!6TXK zMAfCO6+4})E+ooA5*x#^_!?_b!PvDELodVFbpnmPWVa8x-bfy^`J6aqd)nuhTiswB+ic^SAB z{6k|?E4Up{lJ#vaz$=-lmn`U>**P}~3DHVhMCj8swk;S8`$KkONZ22B#_=hLEC*!6 znhF~`V{mLrm?q9!&^fbzu+=%h@e%#@)yc%Ig%uH@Atd$!kj~Nu))n@_k@V}*2hdv@ z21vkahI9i3TWeJu@v@s#u!6B1L%G^gFNJ(w%DOnOcAB^7I<%s4Dd3{KuA_pF$&3tk zhpOT&AYH$>T+%Hv4#LF2J(H0+N4ChvMW!;X2o(xrL7r0YgYY^#o)JYkrN^Bxo(dJ6 zb=Oh-7m!ldRpmO^#{vylWi=X>2#;FMFn6S-hpL8#au=~0hvYk5?c5vzhRxa7jPVh^ z!)+S>Sw83B!wGNz5bXtK{+>JUSn3qZ{qZ?RnPWJ9}DHEhtV$7Bz?|9y zaHUcu(Q#KCN`lmE_s7L;Fndcb=*U=8`UaX)8jI(GceYNY_X^x`#>@q{^^x&r-R=NOGxU zEU7DF4s58T!c3}8tCBBag7g=tC53U|5+BY;pNusBjov673YN~Ah-OME7l2*raoqsT5LewQa_O%VPr|9V`}@6haZA~PsXE0TvGR4SQ*M6wO?h0Txw}a*U1TuCjKndx?mMxP5EHd7yn>^WcMk;Ty*Hb$S8|i zj}jZ;EZTClJmeN6z0?_TQI3Pqd@k>47y#+Z+6hub3&z5sAPs-TWNgPvl!U*_%aT=U z$0u|t#RUR`tgzSy)-R1}xUB5@!E!fJ3v}cvYY2)YE{|ZiLB{N1;rkCb2)jsP;{z0e z|7fNgY)9^bE^y&YgPG9XcYb3BV(%^|6c`@XEm$9jfeA8Qf}SFJ8D{#s<}Kh<=}Gn% zv>eZ{2I63FsdHNy-9-*&ne7hERl8B%Gy|bCmzO&dIOY`y$3}C_RpK%_|5ve1B#I&h zi$;KgYQgl#;)2yX))cAUE<<7vS**VGL8ZU|;uQwSW@|yK4+e{f`N+X0tEv>FoB$gz!x^k(M*gRi=QxVoBmQoQ5JQAV`jYJ|XJF-H{sYYi&h`(_tghlg{9(+XQ5PShrstQ+`Cw>#Y}`nQ*v)OmhaW8cDF zJa}GL@u)Y;oLeNy+#-kv^OO+T%B{;Zyh z`lgRx*xTDRzyH*(-agm`Zyrmw(5NCDFK?|P`wvu+#Kz7i_-P%@?b4Mp z(q%~lJ)hzkXkCfBA1#p9eS(7iC-_`4Ff{v%EKht+ICT89aY&lIku@5VZ6t$HjG)emqY;i$fa%P)3)(u{1J##$0aRywQB`U_L&U z$@joU^KHX?d@PgiJ4hY4o;xrfACr6)>pjwAMdA1=-%id4ZB!TU?L(Gf_Q-zN%uXeq z1{rLKxFP8^O->g2`El zV18dyi|t)Z6HwL7%vrQ3+wsg0j@~Vt+bwQ-^AzKiaF#U5_w<+8=# zIuZTn>n4ol1dQv>_-@ti++dEO^TEt%gE^X%{Ij~;U{{n-K6kQ^F7roRa#PIBQgKP! zjd`R@hgBM4p=5rE)*;p#hn8c0DHW7mlc@TlgSemRU0L&kFJs)l!R#+{XcVLML}?Ob zaIsXQ43y*K?f2cN#E|!YMBM}>4T|C7qb(7g1rxNgEQ?p6*#p(UE}Og7xElCf!?#)k zmGnS0V0f690sAC251T9l?c9NCzz)ExM3-ay6vU*2#L*$n0dD19o?+DpV0hLs~`+C_#mH;>0G{ zrVXaiC&26uU~J=>=;Y)DRB(iy^RFz+oS!A{ic+#Z;B4;$vUXYm19!8)QfKbxZFS~$ z#=k%l&`KA}fn>B%@^K;sTb7BTy5Q|_+pUMHbYy_WOYIV;%K)>JG^&c!AZW&FU!>d^ z2|>V)ae)i}@Ys`BwF=`Sd@F2c*iy40mM?1$U139}Rn~q7BRtTfaUIti*&>iCdeunK zew)nk5>^actiT%RruZaC*RA)CtcVpvNf0Ugb_kJzSl7DEt3(P=a$WotDjz9e?1|;3 zf>(7d&f(X?;b$U+H3LQpYhd-g7OfjvFyI%FDT^@RoQZ~6mtLhNhTbU-26Pc48w?=P ztA#M&?z#&GbP-vC#cVL(Vu-gG450M?JHfzk8w{ZQI2gdCx~Oin93(V! z?~g4U>;3nWIUvV}jZ$RraPKR)Jty5l*RP!-5t>s2=cx-_e`qA#USaWEX3Q5~==V3J z_{i@U7EdD*{H1F>MHK6F>^g)-!}yE{FzdA)i$a%+o8INdEI1DGwHOkMtk-t6s2rTZ zYZn?mWMht86SF?sF)#GlP+3`Y^oCh|wl03c2J&c0BiA*gm_hh#m6ZDIzoLQ-73=h| z&vw?>x#dcWDQ?5v+?dbKIpuZUL!tq6%Grb0WUemxk09TEm)ua{lHWF89MqksiH6`{ z?b<3eSQ~y2RMENDF>tTrd*;vX?wx06EC(3efs4g#zmBZ#Wi#>8 zkfy!f)3H8MH&Ih(;)desV5CuPXa${?V~|^`qs^`Gbbi{a2L(_AXIj0dll6L?%wkad z7a|4;&M>#d<$v;$b547CFE3Zy7%NO=rC}9*R|Oq!YQmcO45_sYXEMJ$kPwIgPcwY!c*b-O#z zh(K;{e&aH-=GT=`XnxT((4^IG=aflnq8;}NYB+48=69rV7B*)=GsCplg6d-GmClgJ zdcHR#ZCw{l=&p1{CSH)b%k_tqsc! zL7f}5Y)X;-AlcSNYbGYH*gkF4O2#aPYM(|0j~xxP*fPc3hhUjxc)@j428Quq8{%S) z)|zd`VOY#@qkr(0DQwKK*L3yZPG^PWLi1Tt`4U564qp+h+iHe$Qt=t&PLdD|7Hl5W6NMo$vvz^6Twnkx`CNdP@4n9<0jLEu0F&ai^8Y`H<_Mek&Q|m3&zl~$qB1fm3oOBd^pE98;>}?g)=45#)5d{ zZCj{%6&2K((g5+unCdg7+*(sM9?{|ZfQv^kLb#~cabC|wEqHgg6{nv>J_tzu;KneH z$L7Ki8N(57T4mnoX7|-7E*k-^YQo8;Bu#kmeMfK%f|~EQ4Ww zzl|PrvJ$(O4tC+F*BJ?T?CuZm`A z0QlL0GG*QXmbmp-9z2CCxk-Usm8(IhlIv0y6fBCi6gQbJ&CzLnYRhPoh;W>E&T=<+CBIoqm}pvw3N*_;c`&cc>e zPP;@Q2QZv4V;UcguquGld3uZrw`3!AWqCEk34xTBV06oSKuW_{%7T^FQf8-O%3;ee zzQ&;;&Xf<{9?S8-G<2YhG?|%N1&P|u`ozOu-uMZ1bCWY|g)pM}Zd)vX|pk zq5X0^Lr=xYNj|5&=(cR%krDDAP3;3|_o*NXRzZ|V+}(OJnU+KTMi6+OGb9B-v8 zud0gafc?eaCFP8WL}%1yMO_s>EC3S~Yt|}k+~LCl@Szv*!vY+}=uelnfN6+am^K^- z74cfII23)=6R*+Y^}$j2^49Ri=#RX3gnM|mYm_;#@#w~V8jo+>rSaItcQ;-ppY}n} z#v?YKAI`~kbX|yJ_pfiC`GTz(JZPnKLTzvER8yEjx@<9 z+G&0bFzdC4eBc_cNxk;4$|cCyAXH^4e)?7IS8RVqb<0DZS(GWjn%X3;tP) zsnqqnAhRZhdb^vRp3SR%9RA14E{q8Vd2kj&#EQ7?weW;hSn+W)qpaNw`{dqk#zk}4 zDSs}3c3QNO9v+d@^%{Rs_&Hsc-VklZld&$#lc*JA53vVuL;hn_-msR8EN|^H{W$-7p;Ld27d-V~%1P zt)H~!P6Dtllp`k4nmanH()|DlKkyv>X5USbeo?;qp+sqcdSf2L+W6x2wtfQm))ude zjy~(x8}@>O65-<%4|f8*9|^DhBnN8S5pd-^3HpxTMsW_&9y1!7_auA{rUe7b^=rjx z>5|E=o`@G0k)zn+wJjFw3_(TR-GoqVe)2OR6Ag-&9ytZU3it(u~WH(>zd9|U{a z`EWkN!cq^K0eujM1X)B=8kY5L2As$#D>+N$`xkuZGX*SV-0`L^9)fT2OqYE9;-NpJ z#omW5AD$eQK#t+$z_0H8#%cup6fALRPQnYUm6-~^ji29|A?}3ySVqKlN#ihz}n0N(z zOCsKq93H#^?2_wd=96v~$@sGs$SDdT%M}$yRtEd3^0Y*@HE<%qZE&oUk2loXZ$QWi z6)_CrPbw-SR>7KgE+ofq{OEU0PD90^%;Cgm;U= z_fvE)?lAPW2o5`4JV?d8xTg7+Opvd*h;*?T_a`^6MI=@njjVu$u`i&(3}T^RbUqqk z6Bvzzm!(0fKLy`ne@edIpUP$&ngf?2HAAitA-WGdWv%K8fA~FKE{4fw$4AS>VC816 zydx?>%Zdnd5tg5vCZSjDcXM=VfoxDdF&N&PN>{D0>$j?aqDF2j4j0gd+)-p{Op!NR zVLyT=QC@ysDXKx%cCWB9LiLy~@={MF%Ey7PE-7MBDZJp4igg3rnI*@aCPXKG5%;W9 zV%OR?CLz`QzE5@+v(bM@6z)bX9ysIg^2p+8o3))PEPf?vPSPs{) zscmPO^7V@ms8&3X@KLq}b2~4Y+JkR2_ql=eXE%^wRf`7_U3EN=wyrXe;LAfW4{}I> zso&LReWY%v&!z>Y2<0KBcqoCDi|=_yhEg1u#zuK>NHYXR&M5n#Bjws_DsBTtR#%y1)JFTpXjpDCA%lI1{SFY~`Fn8Ks?W6V$ZhHF&wPlY~+Q*0m z#T+`4W7W-tX&>`L9^9ElhFHu!vX2q>tbNp=9cl!pxiq)%u1YFmk%&+e1`!czP4bc3 z0Ed3Iu5KSQb|}9uPVtuPw`M->f(@KM;rS>A8Qub_aDJTnV1`gQ^8<9K-UN-ab! zWno(jm2gsQBq+q4*$1=NTSO3BEF@x9dE z!^O4s-g+}h8YfI_F=ENqn>I=gRf>f#l7qI>)`gjY3u?B&SFHWVp}q<2mY@dm;x~%$ z=D_3y{ES#%d{*x{H*V36TvWrlqe?ESvD;qTRf%dOHWr-+D`*B64#Yl78szTM$aSM9 zScc0_QuNHn_vvIyAN>bu6umZp(uysJJq)O87kJ895Xw$0h&C^KvgI$%9w3L>15m{a zs=062iu)m3wKD#^48<&cw<%n8xX93n<~?AQTSb(Q8t9jCbqI-BV6dhuE6AoJx#X=0 zS)+~dHd!!X$WTpm5-huB|;mHSA3;k_jshe!Cq_pq;ZbC`KxrvniMeWdh5(` zFLy~bimaXbwNk=%5m8vO0w0tM zfmzcSODXtdeOytdOW< zbDhj~NO@w}5<$}z?_oLJ>iZUbi*(j6j{dbG<$2&AE zK=vV@zSM?llo@>k!5{CqK9Mgy=3gM$&Ig;tCcNs|j@%K=`1e)p2{oCl?+>*RzlJRu zccAse?zvr)dS>~#`U}ph!R-`#wWZ#x*)6#3t9Ug?PuCN{3V}@4tHIg3H1E~$9R4ne z<{C@=M{^p?{0=$b12-&@0k*I(ULv>Vm({?d*sZbVep$_LQ?bRO=E$dmUMgbEOI9tH zhDe+@bel>?d*ooiAZMTWVNA4d5f|2UdMc4$v>JeH5DJG_a4@nOpu0ff0K3$+$SSjq znQf{O_7pZuGOZB&ksLL2A+J|3vpi5j2|5!3K( zci|FE>1vI9gMTp#mPkd;upuB_%%7e);Dn}=BR1FjO(tcd<`0!9Hh)XYa>hg(6V8~> z`sDM@MryEuAukIHc_Y&jl{=?OUY=11d8y^$%h_GH%GEFXB?q-W@TdqV5Jincmb^zD zpcBNSVwae|e<+sG&PiQR=`@XcAWfH`ZmB&TqGFSA5#kvXh8v=vJhKxE%sCAxozpZ@?0rsr5hzBH;urO^t$w9xE>IdkNgXVu+xVAhk;-oTTJv4_o* zc2SY^YeKpRiMpvL)dX3<$(*RoDU(V{#r->!vda{!P;z(&)A=IjB&+xfciV5o zv99P!sHa;$0LkT?%_~0QM+vz^h1d5HMzdE0a7{A!3 zh69qe9a~iKsbKInext60cO9gnqLOx(Dsrfs`WZSlSDG$U8ZkGZFj*19K^ca=ek(^L zH%Bjk?V`w`R=(IE@~UvC95TpOaqdIvTI5i}XME&z0~T_jb@tbNG+G!$*2kb`@N#;( z5;j!cAy{pvjq!%O%%EVBp#0-d&%C`KpfIubveJ;Zh>;*zbg+o}u~@Bx%y?aoIlnsK z7vokt=Mve&s4&{PxVJ?wFri|)(2xb`N_!Zw$lAkj`rO;Ym_=j{BNml97wn;&>co0% z7_X=tAJ0`TGKLZ7tTCjnz!+kl3PsF+LE~+EW0gOpw{c^*g`ZF420G`D{%+0|=FW=e zzn!M1#2?3y7VC$zpw6|Z^*cl)2xXsE|2^x6K^H#J=>&F&wT$TS z%nI5NEhB&KiB3jDAz}f;U_9P_%NT#4Q+J04V;O0mhi(~h1YuJxBeJSxRHGV>xru}Z zu*b;yeHzu(7zpxW781m$uCfyaT*@aU^_4P}f~+8kjm1jL+hSv*AU84#g*H~}FnAjq znlzw6FZ>4QrWB?E%Llko%l?%Nx-~)n3I;t|Ct6{nTb>gM(XF$KE_`+N>0oQ0-~nTU z?(TZ)mASidb3ZH>`jUbEfW!STWMcC1rdfr_Kh&B07l&Z-WrA9_RTYzuiNpV%$%k53 zHTkd)`Fn?2al;S26?Xu^S$9A&{WILbXlvIcP}a5C!MFp|aueJERw_2t9U$wbx&vfY zcc7j`miJsF3)joW$S{bbQCTWO)*sN5ta3m9fCTX*E3GHNr5Hv%=8Q|u6mbAp_Iy;H z!LeW_{I)n2hPUA(S#A%a(6RXS_9&-oRfT!f%6MDG ze_$1*4PskHzK6i2sFHP!m2%=7MJDLMj#tP@H)UYs@F=ET++T5mMxrp_9bq6xG<8$P zzgvk%m?K1JZH;P<`Iuw}&v)syXQa3KVyVto(I1tY-120xe73x|ipJ=QJL(Yh1_3s^Ty}F} z#fvzySp3*xf>93s>tIZzs#0kw2|A5>^Dz+;%}uSj0gIP-ULJ*@cvomBs(+Fthiw8U z&g`<7RvI_`vRKR_S{93XgjI-J6PCpa3?5kX`CRRyb+L$bc3n(23B>YXt3cY%-pT$< zkZ9fp)5t?zQp_MW3AB;w?D;y5u8R%uGeJ9eCsJ&@oCC@^k=#CeexhVQEF-(^&%3^a zVuJKPl8X8N8hch+773-L5SHT z`@(HztV0L|V_im{ibgn$4#Gi%jq#Wr>%4+yxv{>+o=wM-V9(!4XqFR!8ct%6tIT9* zt;{|wt4U}zqLnq}lQEuYk#yS%4C9>3Y;PddjY{7elr>mLZ{a@Vz_O$%p|_T0OO_2` zDOn7SDm6LjPwcw(R6M8$f(Ix@jvTFY=M_*H*0aD`iP(#*)f?z%Z>{73SC=B$+INvd zJNa$^j=^exSHXXy+(gk(U+69s&Av8fQmU@5NgN8fx=pyP5v%cc807$@eW9yq)`g-< zSd4xJF`GPz6AyYi1xHJZ1FFSv*Y>3pyD7Izm4Hf?5~ZWT3Ii(}P+cF=*pm`a;W_-h zJ~Fv+o?>5i8ygt%Qdgl%#lZ>){$LlibZVY2Hc?0}r2hd>1hTS2ZrIQ9daj0WUMx)k1o`N~yu~K{>Y;E|)ik^;-gnb_>5ytCc zTLP>>)elx{>0&Hlja9O8Bob8#KgPSXEC(XBdQv5vYuCLo`@JD28Q1aOc6AYtx7eRT z;*S{P)R#NI#NQ@H@VUY4A?KH1t|8|o*5aaN?mGh%ue6M#4|1-ku@hMJA5xYM##>W* z;IpE2i9PVC?Tc18M%YP5Bx7F_ZI?v)OSu>r2HysAD5r>sfSvNde(0D4b$z5fRV|5p z?rVGgV6J{vhb<4^?^30Nv{|88m1?bNL|dyrBgU8ttPyF{zHCIQI)q|;M5;O?ETV`s zVo_;pHg!-)5frnY^ookeMy4Eh*s+x;0R~I*QCu3C#%~u%WU2|$DOEclmZ@q)^aGau z_=+3^r2>Z)66a`K2%0zd?oP3raCdW|Ywm5O;`I+6snGS0=g`T{r`q3|P@g&pzpX4S zggbo=o10+VR=HP4!J^nzvf_DH$p%Z~kuNmeMR!^CUG9$*#ja8(pOLEsD%_3KcY>~N(zzw`E$DsB*s83UGxXJFyo zy8>G?Mc!x-x2RJ?=Y;%w0y(eEutYsd)bCl3qWvD;myn)`JW4!?al&~yk$atIj71V@Zro#Ka{aI{IqxhXcgbX(D&d@ScsPc=lhoiUUzN)OE@_MF{wb_Px^}T1VeU{6I_i3Zj5$t@^DMGPA+YeF zW6XkfMW>6AbSrx`7=jYj0oTZ^RnP@Z2nPzQ?+>w8^}9v!9#0%L z4q`zwZYb?cMpg`(<&8m6X>ddBDE-m{0I}W>2>xbYp^00lraAg?zyaQV-`U%jjmMMW zl_Qfzi=Z=6J@;KAUDXxen_Uo;33BuSJ6KOAcQni@mk48-|3c&1@}-#5zv4X?2VS zdCd~$HA>;n+hM54YQBC51JAK!6+U#~Xo>tXthsI#5aF_^VE5Yqi|3SnGC|^kS%& zzU2e?K%i^OBFl=xWt|U&W2#KSh-lfV8b_!*lqzaWp~}iNX7vN8AD*KD2%)mpPcrIw zux49oCu*ZBz*0MX4m{%8%lag8gR@&~t*9!sz%D>?UTsoZS9Ox#LlwkHBGelOCwW45 z|GdrxQV`}yZ#d_O$`?CF#u#>vB&WCQ8ml-*^kL>`ZV*bbb0lBy9Q_N`tdG=9f)-IX zP|mlpnL#iWQ<&7uz!sWxAACd5Z(aR}yd^jyG22l*WP)-QaZaNa5KrMg7BI_m9Xn=+Hk}->DfhA&5*}cI_Rwypm@>!{6%$B1~y<@~S>m4;_ z7IlRh_>r!QDtZha*|Q%{A4JToHBrM5{cw|iyEa};aighf9Gn?VjDxeEueCN+*F&C1 zZQXjvR{1>!f870l+;E3^&kc96M&YY*HjIB~mEjHpwAwCb$_|57NA|TFv(RyIb>u4E zAJ5@$_S;}p4{C`17wsN^MX^1}e3s6?Kg$M-njoLnP3mEXaaQ4qKTM~y;K+P{0TMY1 zf}NM68v0>6on?s=ih^xqgG?lwHy<1akV?gph}5-cfU}Knc}Zjd?t@qoLB9t%LgTYy zpdCSb!oaPnj1Yw%!fLIDx>*pN3yfs@9aJGWSJvfSa%RJN|FFs;Vi08orT#tir#3`X zXA`SOK5KCFsJt@5iPVvgL%a^4X9tBTBfBtCv~s?qpRp9J0Iw=n^#qwkhy02N6-|#eZ0CYK><*63`+??*<)b*Vb;zjT z@6I|F>Q}bUDxxjjTh%B%vW{Sti-K807hI`>#q87uSNa1*$mWcyw~peF^eD4t3lS2= zbBK^K-(+3^>GEcA1J zVN$yX*|RTR4{&s3>yMW-?lJ8)2BEk`b(ke3CsTTO$RmPuSS z2GYml0psXmWM=wyTT!3wH)Xj%2LN9?4)}fFl`l9s`GNVVj(goztqc zwiPvYm&$x&4NyB3#e$I#eNhq%s=CSxSYc>Iv7o9()rGjB?U02t7s?mnWQC;Y>{K@E zmYmqLQQ_M>;U9uR7dRzX#X_fqd6~=wBwrL1zHKvqzAst0TUNA97J|aOopu3XQMkCa zdbpTdI4JsPKmA~>JrB!oKZ%1I%QfUXam5%j;X)$*=rZC4D1md9{H|$h_sp*Oeg0?G z{sDg=BMDsY*n&0_835~dWF zEQQnU{G97(+=-`zuA(q9bQGmdfHMO~<7g~h3dqa^q6Z{Xlgoth=rWz@GGUP8?=t&K zjACXg7CuCjXp{d!h1f1HLNrIr>~t^;7GI4O_@ThU`+==4zv9_qx6bbH%dg(8vm3<# zAYbTEXBx9^y?D7K@7BR8=ho%xDB0zbO1F+|ZW#Ls0ox2k+T`Vu+}Ba0nFFu1==&tu z!zW=H0t#UR>Q(SLlmWPhh1$wrWs=hs+t3GM9;0(@VdS*d^#;p~b>pwta>CI(c|8<) zQzIKb`OVQtupBZm3+eg-KOm-(@u*HtA{I;?Gz;lJujHF@0AAK$a!5)l!mJ#P-dqRX~?-ELJZ zIvj51<&+_rCVy;#^^v-XpeqMMr2-VqIMiiCGY+tFmKKt+dQ7c@jakHvAf2bmkfdt~ zisxRbc#Eb9c09Wgq$SGAfIBUrCN=-LC6Pq2^%DCcuUdwmMRDWJH)R(Gd+JJB%2OfV0-aiH|kNjSAdkx)h{-UD#)>hhtG_ zJ#f=okC;W)dN>x9$`h=ISAeis9ka_?567<1dZ0(4M)_~h`Q2`3Jv3nu){i`+WX341hx`0Et&+j19(j4H546|~Y}xV)8z*+p@9sOVz3beb9)Iw*?1m~1 zH6f?zgl8(P1c5*R23f`~4n4c5fSn>~IJoT6m`#4h8qeWx_H7i=3_Y(s(q_doxv-Ob z<=usN`+D~(MhZF~Ub%tx%IXVs$koiHF;J7hFjF&`!G-r^8q5ihhdqy0Vh%JLBW-e` zKb7u80H)Mx(XKEK7W)%$a-(F2h(w4h$~`blU?nmLs|2VFcyZW>#EW?0fi#@W()?0D zw9n?hQwxU0fn(+^9lvkyyBzscW+IgzhXdheH%)l4Isldm_^vdur_*L5(`)J*3hNNI184c0e(kTn}YYGq{>@3#7}IKqbI zE&Kr7#lmA9gK_f)a}?)Bm~h~LmArq4VqbnrLJN2;)J)Zr4iS5%uHaCO|-4pEH2oqTG1Gd5BmwU606 z()73#|Akj6g+GmflT3Pej!F~WN^&~I!6pq5zoc)J=pb~8%x8o~&<@i7La=X>bg;7q zi`5!rKVPey!9gs5=i#M3Bp#IfDB}&0G(h;ONzu{g=IZv8!tT|*#u~p4k+XR)p)gbf z*({@^Jj8}En^ zF-gKVGOQMApe%ZfGp@N-5yn95ybUx=&8`PkVx2F}60IUJ~CYrE;lQR*#BfTk+K=vys zJ`xBY`f!8TM*@MSR8GveN zqn#p@;Ix)JMcHYYP_*#JO7>MGgjOk4de?|u*1M7&juDAH zhT-vgpY^UHhYhCDd)Gm{Nuf1~ysPdQWj+m)^RCWsxSgSb5XRk#%|0Wsbw2K~cdXgx zo!~mv;Z`mi@|6kdAI$R*|0|atK(|x=?$3UZ6Lg{8bhMA3(9)i8LM&tlzh=^4rZ%-t zY@Rxy1(!A0dvcfUNiFi6*3!m2b;u(m9;(MfpgYd!;GGgUxGUToh7aX8x3^DjKe45? zxvgnZb21!n5Vy3QIN2vOAV1c26NVY&?OUJa1=JsSu1P>=pZk^EFK4U_2$H`MC zPf4~iTezeSv}x+3=C*0c=X%eg0k&MB9*7(VjCQWX$*V~}L zNzD^lnv!=Qj@ME&M@Ok$J809>9p3VX@Ub| zXy&O+t<##*6jC~gt(ie+YHdwxka9xP)bS_zlv+exlO|7SPU|3)*2xo3YHFL%+ML$o zm+3m1TTxQ;gc+?(Z4;+8O>BOzynj$K3wnFz^mfjp?#K%X2p=)@$w{=xrhN{VF3qNV z%RPlBYwK*<4>8^2Q||irK9@^*8BFc;YKSr-jYVYp@b>e-Ky8PpyRgw~= zovlyR*14z7*Qe_6$EAG$dTVOywWMntXJ6M(K}VG{>Qh@|YjBT$&eiGr(Q}lLeeP)} zvCGZ+hCAi>d0*OYscV^&#kyR|`&^2b*D<-2xljUIuC2#peIm%>E6^fW#_hTM4`_bZ z15ZM8$gdW^^ynn_dWxuky&(V9);QTrfQ4|+oEXu^<3Z*o4_m9Fyl%bQQ{50zjelY; zG^eJnrlwxyKAk)$#afp#O>`^dSRgq}ZH@NmsiKdz-mX@ys8vbtUtl@1ZCb{?NI{u( zp|5TN50~P4b_@m{(`-w&6Zxj!ci+`~v6N$F z7@k2-s=m#Tp5%R(V^%KZRq5OCL@zD6=D!q;4(+~z6_fsQWt~pFhx9puY|E!}{2;|% zeHi_iU<-cYgcf|~O@35s^11Krn%U21N_C~W1TV?q=2m86SO3(mi~E}|?#GWwPU-2M zk4I$Q1=-Z$F?>M^#&|Q+JiqhYxm~Aq&!5$Ek!6zBB{l9YxQw6M+1J$S{oePVAYvun+Ap3BGeiHk&im)}Xa# z{v4kvf4kkc6itBOD{`OK(>u%O))o#kEqyIBd**k~)M`fQuGLa~O&^8lZMu~V7|LxG zNrRcxbD)iZ(mO@ zYk($bR(u)al0K-*lukIruKupxzLxp3dn^xXtFr=({_Qy6XR$4{H8{Dk$m5VUbz4vI z?3_*8&Qsfa>Ybk2*;BiCYA;Xi?Wuh{wXdh%<*6e`QARWRX7QJL(H(5Y+^*UEAmnFz z@o$~!?VfWUQ`~R$+8iA%XEwv?k;Tl5?LU`nQ)f0uZ<#F#V+dmbX(M4*!afAXe~_xBHR6mc z9ZA@duqVJAPU<+qIKo82dkE(MOb@B|ky=UW22%W9c={x%VQlMG0MkV3WI(cn)J>$m zMd~pC30E$W07&>bkF*VHl&&W{Mc9(t z{<{Ivg9!5omjjXy5pE>hLAVQG9tWg1V#PcC5@8#}{^==%b%eVJ2vJRX6z63NNqq>A ze3jHsnD#%UMsS^O3LrTHke)}XhtNy-G}FFD>d&O!Bz4G0P$vSCOG$m0)J>$GC$$6K zuS!lQEGK*qkp7a?Ur4D!(I@^2=_=1JW}IiwPSDza=~mNZufY z&-|OD5s)5DI1OO#CiM{E7lh{sjToBgIKo`Qb%fgh=0QO6LtdVaHK}wy;cCKK!j}o( zB-G=;UAhC|5W-1>_Y-a=JVy8*!p`piyob<7c#Uul#(jDLVM~nrbQi+;ge@@m(`yKC z5DtL_NSg^?pe=X`ki5vtNjm_(O}G!HA$^@NZzsUkjesY126XNM_&s6wT>-6x)r98= zlXe5ETL9@d39k_j-W||Q_$1+oJ@Ck%0cpA?U^L+x!fJrI9gu9`<-Mf7L)aOHC^?pJ zCLp~AU_MRin}kF62FwGP50m;F;k&$ij_@ksO{O)`bTtE#4nR7Gm)DW{8L3hGf|?F6 zOGy2S)ad;HPZEyYA20=wo<*vY)O=F66Yc;ccQNf-q#h(ZO{hNrusa}qA7K%|{3qeN zgh!b6dqR33V1L3_3Eu*kUjUL{^YV|Ro+q4q5MVYST?sH>CiN&`+`)iL0cJU=4TK-@ z@^wP(A%GEp^mtO^0m&)6?BeCMq<%uG;ZRUh0p=RQ^@jnTCDgtPH?{Z}#V~+sr1u!Q7l4f4Ek(x&83V>Nl>Q2Hw zN8)lSVJ4v$kS-xS$je6n$&dr=0m4;)*5e8OsgIdeSV4#J~=^yj30P3l=v2TcGR21t$oq~l0UB+TUH zJ%on==4qxq!^^*sdX3a>&A9PyKsuf9C}G%%NZSRFjw3YzkhJr1HZPBx2v|Y*A|Sn+ z)V-u0A~otHz-U0S4Itf#)E=a+BrFD)FEH(kyu5?dJ*55!Flh_^ZzL=wJP0t40Fs~c z@_Akke-EgA2ox>rWMdj_$VMNJ3PA0WAzm-q1U52Us@3$Q!D98c;j!efNt zXCrM_K-xsA8IYX9%Pztfn06njmq=|p19$fYm`eyhA?$Sy(vAU`<)l6fNdHFIw-afT z0m-?f76Z~xkopvG9RcPDKyoxM z$CG*wsf7S@J*is=J9Yu40?g@vWEL+k=H+Iy0q-Sz5RhI^Y8j~;Nd2DhM?mstroBY! z4N|Ag0n7%ND*(w=yj( zKP5E27ilL0()SWp^K!rQ0UssY2uN=u^;J^;MXGi#U>G170Z6wdwLPhYgsTZ(1(-)j zy+YW29^g2_H30KPQg4z<=OgbHfOI#)WrXVpUnKmHa6}KDI|h)p5q?kDe*xfFfH@VA zoWaX;Np%yx!^@WeX4D0sCJ{bO7}E=AC47*ujPMxYH-zo_kmE2yGa%^zq;q(A9jVWd zdQj5(K`mJbc!4nNLfjn#Fk?yWLFxj+LO^mc)2<}-5yH*9thorV6~OEVNDk!Xk))0% ztmEaw0P{4d+KT}f621&D-y?O{C4gm@;&K%r`3xYvi?GA{0M`;;2bf=81~~ftfObGS zgVan?3rMXe+zCj&&b0eTJw*5uFHgH1FdJa503=uOauKOzgy(s=;|Fl}2tYcGa6cir z0%_X=(ql=TO6n?79|j~Vc=>rk=}M$MN0|6Qzzje-m(&7M?gS|hCN*vm zs0o0i9gxl@+($V0I>3Jb%+((Q{EF}jAg#F`R0)u7P3m;QbU-qLY3GsZAzVkeh43IC zJzz0lB4HNc0>T#n<~~4jKQF&e>ZgQ5m*8?Hz`UQ-^@KHq5laCl0L*McKQGr19^>UR zq#Bli+KuooKr$YXUPlCyX@o76nQgS>nVU`F4_hY6o1{1RYZB{k;LpvD4{Jpt)4yzC@(38_yI ze#*<|NsYb<)b)g)0L+u5o&_Y0pTXrf2;1EZI0TR$Pij1=DWq;B+zd!Q&$Qb~-9`8* zFOU2zU?RYD0+Lz0oJXpk)F%PvE>b@ww0sV56~KIg)P1BL03?s|@=v_n;`4wX5DxkR z;3Pmgjno;WW|K;90n`JM;ed22Qe#P-PqfzDj8O3Sc%M z?IU#&sjEpnKzJCCJjS#qNd21Bgxdif05cDeEa2rOq^=D@v@)PB2r%_Rlfn$v4C_M;WLCkGwpd&=^e;>IKcdnaOl?nCj-*c zNlho!O=>;iPC)W?rrk&CA;L4fJoiq(j|n60!gHel$&RFU2Bb%kI*Zg3q)xdT@KwS? zfbEOi;2c0YkJJUE zE+_RM;SoUceWpE0>NkYf3EO@P&;>|8LAVuQzRR=+dHF+9PZDasjmu;1!`*3sw2$x< zVW;mP?I=KcCaHc>OG&K+BscN$PQr79d>WA4%(UA`-9h*PFHiglU^(G7 zfO!y*Jj~0VkopDT$j1Tgfb?>JSxxE=!ofcUoJY6}U{;d)8mS+U`WxZMCjhevw*t)f z0Lc@)e3o#|lYq+!Ujvv&0LkOL?D!dA6~OHKbHJs9rGWI4q&`jR%cNc+B)`D_wSaVU MQd<)aB(wnj4?UUG^8f$< literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.rul b/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.rul new file mode 100644 index 00000000000..0db8417a62c --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/Script Files/Setup.rul @@ -0,0 +1,641 @@ + +//////////////////////////////////////////////////////////////////////////////// +// +// IIIIIII SSSSSS +// II SS InstallShield (R) +// II SSSSSS (c) 1996-1997, InstallShield Software Corporation +// II SS (c) 1990-1996, InstallShield Corporation +// IIIIIII SSSSSS All Rights Reserved. +// +// +// This code is generated as a starting setup template. You should +// modify it to provide all necessary steps for your setup. +// +// +// File Name: Setup.rul +// +// Description: InstallShield script +// +// Comments: This template script performs a basic setup on a +// Windows 95 or Windows NT 4.0 platform. With minor +// modifications, this template can be adapted to create +// new, customized setups. +// +//////////////////////////////////////////////////////////////////////////////// + + + // Include header file +#include "sdlang.h" +#include "sddialog.h" + +////////////////////// string defines //////////////////////////// + +#define UNINST_LOGFILE_NAME "Uninst.isu" + +//////////////////// installation declarations /////////////////// + + // ----- DLL prototypes ----- + + + // your DLL prototypes + + + // ---- script prototypes ----- + + // generated + prototype ShowDialogs(); + prototype MoveFileData(); + prototype HandleMoveDataError( NUMBER ); + prototype ProcessBeforeDataMove(); + prototype ProcessAfterDataMove(); + prototype SetupRegistry(); + prototype SetupFolders(); + prototype CleanUpInstall(); + prototype SetupInstall(); + prototype SetupScreen(); + prototype CheckRequirements(); + prototype DialogShowSdWelcome(); + prototype DialogShowSdShowInfoList(); + prototype DialogShowSdAskDestPath(); + prototype DialogShowSdSetupType(); + prototype DialogShowSdComponentDialog2(); + prototype DialogShowSdFinishReboot(); + + // your prototypes + + + // ----- global variables ------ + + // generated + BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup; + STRING svDir; + STRING svName, svCompany, svSerial; + STRING szAppPath; + STRING svSetupType; + + + // your global variables + + +/////////////////////////////////////////////////////////////////////////////// +// +// MAIN PROGRAM +// +// The setup begins here by hiding the visible setup +// window. This is done to allow all the titles, images, etc. to +// be established before showing the main window. The following +// logic then performs the setup in a series of steps. +// +/////////////////////////////////////////////////////////////////////////////// +program + Disable( BACKGROUND ); + + CheckRequirements(); + + SetupInstall(); + + SetupScreen(); + + if (ShowDialogs()<0) goto end_install; + + if (ProcessBeforeDataMove()<0) goto end_install; + + if (MoveFileData()<0) goto end_install; + + if (ProcessAfterDataMove()<0) goto end_install; + + if (SetupRegistry()<0) goto end_install; + + if (SetupFolders()<0) goto end_install; + + + end_install: + + CleanUpInstall(); + + // If an unrecoverable error occurred, clean up the partial installation. + // Otherwise, exit normally. + + if (bInstallAborted) then + abort; + endif; + +endprogram + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: ShowDialogs // +// // +// Purpose: This function manages the display and navigation // +// the standard dialogs that exist in a setup. // +// // +/////////////////////////////////////////////////////////////////////////////// +function ShowDialogs() + NUMBER nResult; + begin + + Dlg_Start: + // beginning of dialogs label + + Dlg_SdWelcome: + nResult = DialogShowSdWelcome(); + if (nResult = BACK) goto Dlg_Start; + + Dlg_SdShowInfoList: + nResult = DialogShowSdShowInfoList(); + if (nResult = BACK) goto Dlg_SdWelcome; + + Dlg_SdAskDestPath: + nResult = DialogShowSdAskDestPath(); + if (nResult = BACK) goto Dlg_SdShowInfoList; + + Dlg_SdSetupType: + nResult = DialogShowSdSetupType(); + if (nResult = BACK) goto Dlg_SdAskDestPath; + + Dlg_SdComponentDialog2: + if ((nResult = BACK) && (svSetupType != "Custom") && (svSetupType != "")) then + goto Dlg_SdSetupType; + endif; + nResult = DialogShowSdComponentDialog2(); + if (nResult = BACK) goto Dlg_SdSetupType; + + return 0; + + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: ProcessBeforeDataMove // +// // +// Purpose: This function performs any necessary operations prior to the // +// actual data move operation. // +// // +/////////////////////////////////////////////////////////////////////////////// +function ProcessBeforeDataMove() + STRING svLogFile; + NUMBER nResult; + begin + + InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY ); + + svLogFile = UNINST_LOGFILE_NAME; + + nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 ); + if (nResult < 0) then + MessageBox( @ERROR_UNINSTSETUP, WARNING ); + endif; + + szAppPath = TARGETDIR; // TODO : if your application .exe is in a subdir of TARGETDIR then add subdir + + if ((bIs32BitSetup) && (bIsShellExplorer)) then + RegDBSetItem( REGDB_APPPATH, szAppPath ); + RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY ); + RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME ); + endif; + + // TODO : update any items you want to process before moving the data + // + + return 0; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: MoveFileData // +// // +// Purpose: This function handles the data movement for // +// the setup. // +// // +/////////////////////////////////////////////////////////////////////////////// +function MoveFileData() + NUMBER nResult, nDisk; + begin + + nDisk = 1; + SetStatusWindow( 0, "" ); + Disable( DIALOGCACHE ); + Enable( STATUS ); + StatusUpdate( ON, 100 ); + nResult = ComponentMoveData( MEDIA, nDisk, 0 ); + + HandleMoveDataError( nResult ); + + Disable( STATUS ); + + return nResult; + + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: HandleMoveDataError // +// // +// Purpose: This function handles the error (if any) during the move data // +// operation. // +// // +/////////////////////////////////////////////////////////////////////////////// +function HandleMoveDataError( nResult ) + STRING szErrMsg, svComponent , svFileGroup , svFile; + begin + + svComponent = ""; + svFileGroup = ""; + svFile = ""; + + switch (nResult) + case 0: + return 0; + default: + ComponentError ( MEDIA , svComponent , svFileGroup , svFile , nResult ); + szErrMsg = @ERROR_MOVEDATA + "\n\n" + + @ERROR_COMPONENT + " " + svComponent + "\n" + + @ERROR_FILEGROUP + " " + svFileGroup + "\n" + + @ERROR_FILE + " " + svFile; + SprintfBox( SEVERE, @TITLE_CAPTIONBAR, szErrMsg, nResult ); + bInstallAborted = TRUE; + return nResult; + endswitch; + + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: ProcessAfterDataMove // +// // +// Purpose: This function performs any necessary operations needed after // +// all data has been moved. // +// // +/////////////////////////////////////////////////////////////////////////////// +function ProcessAfterDataMove() + begin + + // TODO : update self-registered files and other processes that + // should be performed after the data has been moved. + + + return 0; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: SetupRegistry // +// // +// Purpose: This function makes the registry entries for this setup. // +// // +/////////////////////////////////////////////////////////////////////////////// +function SetupRegistry() + NUMBER nResult; + + begin + + // TODO : Add all your registry entry keys here + // + // + // RegDBCreateKeyEx, RegDBSetKeyValueEx.... + // + + nResult = CreateRegistrySet( "" ); + + return nResult; + end; + +/////////////////////////////////////////////////////////////////////////////// +// +// Function: SetupFolders +// +// Purpose: This function creates all the folders and shortcuts for the +// setup. This includes program groups and items for Windows 3.1. +// +/////////////////////////////////////////////////////////////////////////////// +function SetupFolders() + NUMBER nResult; + + begin + + + // TODO : Add all your folder (program group) along with shortcuts (program items) + // + // + // CreateProgramFolder, AddFolderIcon.... + // + + nResult = CreateShellObjects( "" ); + + return nResult; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: CleanUpInstall // +// // +// Purpose: This cleans up the setup. Anything that should // +// be released or deleted at the end of the setup should // +// be done here. // +// // +/////////////////////////////////////////////////////////////////////////////// +function CleanUpInstall() + begin + + + if (bInstallAborted) then + return 0; + endif; + + DialogShowSdFinishReboot(); + + if (BATCH_INSTALL) then // ensure locked files are properly written + CommitSharedFiles(0); + endif; + + return 0; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: SetupInstall // +// // +// Purpose: This will setup the installation. Any general initialization // +// needed for the installation should be performed here. // +// // +/////////////////////////////////////////////////////////////////////////////// +function SetupInstall() + begin + + Enable( CORECOMPONENTHANDLING ); + + bInstallAborted = FALSE; + + if (bIs32BitSetup) then + svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME; + else + svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; // use shorten names + endif; + + TARGETDIR = svDir; + + SdProductName( @PRODUCT_NAME ); + + Enable( DIALOGCACHE ); + + return 0; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: SetupScreen // +// // +// Purpose: This function establishes the screen look. This includes // +// colors, fonts, and text to be displayed. // +// // +/////////////////////////////////////////////////////////////////////////////// +function SetupScreen() + begin + + Enable( FULLWINDOWMODE ); + Enable( INDVFILESTATUS ); + SetTitle( @TITLE_MAIN, 24, WHITE ); + + SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text. + + Enable( BACKGROUND ); + + Delay( 1 ); + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: CheckRequirements // +// // +// Purpose: This function checks all minimum requirements for the // +// application being installed. If any fail, then the user // +// is informed and the setup is terminated. // +// // +/////////////////////////////////////////////////////////////////////////////// +function CheckRequirements() + NUMBER nvDx, nvDy, nvResult; + STRING svResult; + + begin + + bWinNT = FALSE; + bIsShellExplorer = FALSE; + + // Check screen resolution. + GetExtents( nvDx, nvDy ); + + if (nvDy < 480) then + MessageBox( @ERROR_VGARESOLUTION, WARNING ); + abort; + endif; + + // set 'setup' operation mode + bIs32BitSetup = TRUE; + GetSystemInfo( ISTYPE, nvResult, svResult ); + if (nvResult = 16) then + bIs32BitSetup = FALSE; // running 16-bit setup + return 0; // no additional information required + endif; + + // --- 32-bit testing after this point --- + + // Determine the target system's operating system. + GetSystemInfo( OS, nvResult, svResult ); + + if (nvResult = IS_WINDOWSNT) then + // Running Windows NT. + bWinNT = TRUE; + + // Check to see if the shell being used is EXPLORER shell. + if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then + if (nvResult >= 4) then + bIsShellExplorer = TRUE; + endif; + endif; + + elseif (nvResult = IS_WINDOWS95 ) then + bIsShellExplorer = TRUE; + + endif; + +end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdWelcome // +// // +// Purpose: This function handles the standard welcome dialog. // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdWelcome() + NUMBER nResult; + STRING szTitle, szMsg; + begin + + szTitle = ""; + szMsg = ""; + nResult = SdWelcome( szTitle, szMsg ); + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdShowInfoList // +// // +// Purpose: This function displays the general information list dialog. // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdShowInfoList() + NUMBER nResult; + LIST list; + STRING szTitle, szMsg, szFile; + begin + + szFile = SUPPORTDIR ^ "infolist.txt"; + + list = ListCreate( STRINGLIST ); + ListReadFromFile( list, szFile ); + szTitle = ""; + szMsg = " "; + nResult = SdShowInfoList( szTitle, szMsg, list ); + + ListDestroy( list ); + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdAskDestPath // +// // +// Purpose: This function asks the user for the destination directory. // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdAskDestPath() + NUMBER nResult; + STRING szTitle, szMsg; + begin + + szTitle = ""; + szMsg = ""; + nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 ); + + TARGETDIR = svDir; + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdSetupType // +// // +// Purpose: This function displays the standard setup type dialog. // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdSetupType() + NUMBER nResult, nType; + STRING szTitle, szMsg; + begin + + switch (svSetupType) + case "Typical": + nType = TYPICAL; + case "Custom": + nType = CUSTOM; + case "Compact": + nType = COMPACT; + case "": + svSetupType = "Typical"; + nType = TYPICAL; + endswitch; + + szTitle = ""; + szMsg = ""; + nResult = SetupType( szTitle, szMsg, "", nType, 0 ); + + switch (nResult) + case COMPACT: + svSetupType = "Compact"; + case TYPICAL: + svSetupType = "Typical"; + case CUSTOM: + svSetupType = "Custom"; + endswitch; + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdComponentDialog2 // +// // +// Purpose: This function displays the custom component dialog. // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdComponentDialog2() + NUMBER nResult; + STRING szTitle, szMsg; + begin + + if ((svSetupType != "Custom") && (svSetupType != "")) then + return 0; + endif; + + szTitle = ""; + szMsg = ""; + nResult = SdComponentDialog2( szTitle, szMsg, svDir, "" ); + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdFinishReboot // +// // +// Purpose: This function will show the last dialog of the product. // +// It will allow the user to reboot and/or show some readme text. // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdFinishReboot() + NUMBER nResult, nDefOptions; + STRING szTitle, szMsg1, szMsg2, szOption1, szOption2; + NUMBER bOpt1, bOpt2; + begin +/* + if (!BATCH_INSTALL) then + bOpt1 = FALSE; + bOpt2 = FALSE; + szMsg1 = ""; + szMsg2 = ""; + szOption1 = ""; + szOption2 = ""; + nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 ); + return 0; + endif; + + nDefOptions = SYS_BOOTMACHINE; + szTitle = ""; + szMsg1 = ""; + szMsg2 = ""; + nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 ); +*/ + return nResult; + end; + + // --- include script file section --- + +#include "sddialog.rul" + + + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt b/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt new file mode 100644 index 00000000000..2f561d29d81 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt @@ -0,0 +1,24 @@ +This is a release of MySQL 3.23.56 for Win32. + +NOTE: If you install MySQL in a folder other than +C:\MYSQL or you intend to start MySQL on NT/Win2000 +as a service, you must create a file named C:\MY.CNF +or \Windows\my.ini or \winnt\my.ini with the following +information:: + +[mysqld] +basedir=E:/installation-path/ +datadir=E:/data-path/ + +After your have installed MySQL, the installation +directory which contains the files named 'my-size.cnf'. +You can use this as a starting point for your own +C:\my.cnf file. + +If you have any problems, you can mail them to +win32@lists.mysql.com after you have consulted the +MySQL manual and the MySQL mailing list archive +(http://www.mysql.com/documentation/index.html) + +On behalf of the MySQL AB gang, +Michael Widenius \ No newline at end of file diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP b/VC++Files/InstallShield/3.23.XX-gpl/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP new file mode 100644 index 0000000000000000000000000000000000000000..3229d50c9bfcabefefb1341fda098d20bcc734b1 GIT binary patch literal 15694 zcmeI3JB%Ae7{@=K-(K76_xXH&Oi7uF4k@AsrK3$jjnYv@G&D%0il|5m3XnjGA{wMf zL_$gf5>dL)5Cs$g3Mf1j1%y!e9<#Hv>lu6R&bNC-MzTHL8PERqKl43y_U_f!UVjC+ zyj%fz32PtY>kWLBpuxxK?R+3FJjmtqYZu|WZ*RcE`?ulUHv!&%s|Q!#R`B6F=isCF z&ckO{FTkx&F2PqfFT>ZjuE4!J*Wu?M?!xcCK7eOWpTLDLet}DOegpX60rajt1ohF6 zaPHGbaQ@~`aPiB>aQT}jaOK_~aQ*&YaO3-@aQo3Sxcm4Yc<|@H@Z|6R;Q90C0`lVh zg#s@W$Xx-Iz0}KVrP>I(*#|g5PdLJF9h?MS&x3RaoaIXA2p4(N7hE}BaV%I}cL;-qtVlj;-e}&Za^l2$Z)OHw_D6{(`O=TtSF@fhgG48#CUZ5I z4yV%;XV*{|iEYl7X*P&l@o}PΞYl3Pc*AWK<5_&B8evjnkZ9&L1hLEKZN3FPHtC zgCT>?5;ECe7}VFS7UP5EU_2Y7IJ*Y3T#lkl%-NFG1}ZO3c5Stn=?H{M=3C@t0UsXOLL1Rv?)sh2j;#7Uc!oV)f#O2xiD zE2oZ)!+pu!@cmHdAUoAF7Leq`#FY7(+4U4TM^10OLp^0dM#+bYeSNGaI{~k~3kxqt zxl-$WcbsD24Qp)i^?|)U>sU}>yL9MSog#v;aGGX!;QEO&v7T$E zPaHT!&ae?^&Irmrv!Gj^)NWj_3ukc$>f{1s;@8{c_Q}f`(v2f; zUxCan!Bk?WB!Y&qpi!98O1nSy9UOSbikxd5l;a=PPBqbiXYHqRLtOqP!C}X zK_KR|rPpbbhqcYmO1kKs*y@YnEHxUu?T5ZRHfe_@K_v>4g>X{t!`VcwoX&l0*buYL zn%>4Ng0n<6OtGf9@d+6{D$vor5PL@#4v5;II~yzF*h(tZX=1KqrA7tl8DQdzn=f@$ z$CtBo2@`Fq~%*lrvfEPylc z_#-C8OvNxZ6C3-JN%Hw7~(%ITmJ|$;bPq z7noXZ6%3i4bD@tEAR!PIiA;39M0e2K&!p`kHC|5(v1i{ zCh`{Wwwz8w)gu~O*Tz2|&Y2UpU!4I5U6R*zvS2xL;!cfgo(R+Hl8WFo)1Fw1gtPi^BL1w{geV-aho6HBV0Tk*Q3+gPELuAnYZSh8#I@A1)afyR literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Shell Objects/Default.shl b/VC++Files/InstallShield/3.23.XX-gpl/Shell Objects/Default.shl new file mode 100644 index 00000000000..187cb651307 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/Shell Objects/Default.shl @@ -0,0 +1,12 @@ +[Data] +Folder3= +Group0=Main +Group1=Startup +Folder0= +Folder1= +Folder2= + +[Info] +Type=ShellObject +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/String Tables/0009-English/value.shl b/VC++Files/InstallShield/3.23.XX-gpl/String Tables/0009-English/value.shl new file mode 100644 index 00000000000..687c58b7b21 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/String Tables/0009-English/value.shl @@ -0,0 +1,23 @@ +[Data] +TITLE_MAIN=MySQL Servers and Clients 3.23.56 +COMPANY_NAME=MySQL AB +ERROR_COMPONENT=Component: +COMPANY_NAME16=Company +PRODUCT_VERSION=3.23.56 +ERROR_MOVEDATA=An error occurred during the move data process: %d +ERROR_FILEGROUP=File Group: +UNINST_KEY=MySQL Servers and Clients 3.23.56 +TITLE_CAPTIONBAR=MySQL Servers and Clients 3.23.56 Setup +PRODUCT_NAME16=Product +ERROR_VGARESOLUTION=This program requires VGA or better resolution. +ERROR_FILE=File: +UNINST_DISPLAY_NAME=MySQL Servers and Clients 3.23.56 +PRODUCT_KEY=yourapp.Exe +PRODUCT_NAME=MySQL Servers and Clients 3.23.56 +ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able to uninstall this product. + +[General] +Language=0009 +Type=STRINGTABLESPECIFIC +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/String Tables/Default.shl b/VC++Files/InstallShield/3.23.XX-gpl/String Tables/Default.shl new file mode 100644 index 00000000000..d4dc4925ab1 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/String Tables/Default.shl @@ -0,0 +1,74 @@ +[TITLE_MAIN] +Comment= + +[COMPANY_NAME] +Comment= + +[ERROR_COMPONENT] +Comment= + +[COMPANY_NAME16] +Comment= + +[PRODUCT_VERSION] +Comment= + +[ERROR_MOVEDATA] +Comment= + +[ERROR_FILEGROUP] +Comment= + +[Language] +Lang0=0009 +CurrentLang=0 + +[UNINST_KEY] +Comment= + +[TITLE_CAPTIONBAR] +Comment= + +[Data] +Entry0=ERROR_VGARESOLUTION +Entry1=TITLE_MAIN +Entry2=TITLE_CAPTIONBAR +Entry3=UNINST_KEY +Entry4=UNINST_DISPLAY_NAME +Entry5=COMPANY_NAME +Entry6=PRODUCT_NAME +Entry7=PRODUCT_VERSION +Entry8=PRODUCT_KEY +Entry9=ERROR_MOVEDATA +Entry10=ERROR_UNINSTSETUP +Entry11=COMPANY_NAME16 +Entry12=PRODUCT_NAME16 +Entry13=ERROR_COMPONENT +Entry14=ERROR_FILEGROUP +Entry15=ERROR_FILE + +[PRODUCT_NAME16] +Comment= + +[ERROR_VGARESOLUTION] +Comment= + +[ERROR_FILE] +Comment= + +[General] +Type=STRINGTABLE +Version=1.00.000 + +[UNINST_DISPLAY_NAME] +Comment= + +[PRODUCT_KEY] +Comment= + +[PRODUCT_NAME] +Comment= + +[ERROR_UNINSTSETUP] +Comment= + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Build.tsb b/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Build.tsb new file mode 100644 index 00000000000..3949bd4c066 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Build.tsb @@ -0,0 +1,56 @@ +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[Data] +Key0= +Key1= +Key2= +Key3= +Key4= +Key5= +Key6= +Key7= +Key8= +Key9= + +[General] +Type=TEXTSUB +Version=1.00.000 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + diff --git a/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Setup.tsb b/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Setup.tsb new file mode 100644 index 00000000000..b0c5a509f0b --- /dev/null +++ b/VC++Files/InstallShield/3.23.XX-gpl/Text Substitutions/Setup.tsb @@ -0,0 +1,76 @@ +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[Data] +Key0= +Key1= +Key2= +Key3= +Key4= +Key5= +Key10= +Key6= +Key11= +Key7= +Key12= +Key8= +Key13= +Key9= + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[General] +Type=TEXTSUB +Version=1.00.000 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + +[] +Value= +KeyType=4 + diff --git a/VC++Files/InstallShield/3.23.XXcom/Component Definitions/.fgl b/VC++Files/InstallShield/3.23.XXcom/Component Definitions/.fgl new file mode 100644 index 00000000000..81e474f9be8 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/Component Definitions/.fgl @@ -0,0 +1,37 @@ +[General] +Type=FILELIST +Version=1.00.000 + +[topdir] +subdir0= +subdir1= +subdir2= +subdir3=USERDEFINED + +[] +DISPLAYTEXT=Windows Operating System +TYPE=TEXTSUBFIXED +subdir0=\ + +[\] +DISPLAYTEXT=Windows System Folder +TYPE=TEXTSUBFIXED + +[] +DISPLAYTEXT=Program Files Folder +TYPE=TEXTSUBFIXED +subdir0=\ + +[\] +DISPLAYTEXT=Common Files Folder +TYPE=TEXTSUBFIXED + +[] +DISPLAYTEXT=General Application Destination +TYPE=TEXTSUBFIXED + +[USERDEFINED] +DISPLAYTEXT=Script-defined Folders +TYPE=USERSTART + + diff --git a/VC++Files/InstallShield/3.23.XXcom/Component Definitions/Default.cdf b/VC++Files/InstallShield/3.23.XXcom/Component Definitions/Default.cdf new file mode 100644 index 00000000000..f44131f754e --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/Component Definitions/Default.cdf @@ -0,0 +1,192 @@ +[Development] +required0=Servers +SELECTED=Yes +FILENEED=STANDARD +required1=Grant Tables +HTTPLOCATION= +STATUS=Examples, Libraries, Includes and Script files +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=Examples, Libraries, Includes and Script files +DISPLAYTEXT=Examples, Libraries, Includes and Script files +IMAGE= +DEFSELECTION=Yes +filegroup0=Development +COMMENT= +INCLUDEINBUILD=Yes +INSTALLATION=ALWAYSOVERWRITE +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + +[Grant Tables] +required0=Servers +SELECTED=Yes +FILENEED=CRITICAL +HTTPLOCATION= +STATUS=The Grant Tables and Core Files +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=The Grant Tables and Core Files +DISPLAYTEXT=The Grant Tables and Core Files +IMAGE= +DEFSELECTION=Yes +filegroup0=Grant Tables +requiredby0=Development +COMMENT= +INCLUDEINBUILD=Yes +requiredby1=Clients and Tools +INSTALLATION=NEVEROVERWRITE +requiredby2=Documentation +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + +[Components] +component0=Development +component1=Grant Tables +component2=Clients and Tools +component3=Servers +component4=Documentation + +[TopComponents] +component0=Servers +component1=Clients and Tools +component2=Documentation +component3=Development +component4=Grant Tables + +[SetupType] +setuptype0=Compact +setuptype1=Typical +setuptype2=Custom + +[Servers] +SELECTED=Yes +FILENEED=CRITICAL +HTTPLOCATION= +STATUS=The MySQL Servers +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=The MySQL Servers +DISPLAYTEXT=The MySQL Servers +IMAGE= +DEFSELECTION=Yes +filegroup0=Servers +requiredby0=Development +COMMENT= +INCLUDEINBUILD=Yes +requiredby1=Grant Tables +INSTALLATION=ALWAYSOVERWRITE +requiredby2=Clients and Tools +requiredby3=Documentation +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + +[Clients and Tools] +required0=Servers +SELECTED=Yes +FILENEED=HIGHLYRECOMMENDED +required1=Grant Tables +HTTPLOCATION= +STATUS=The MySQL clients and Maintenance Tools +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=The MySQL clients and Maintenance Tools +DISPLAYTEXT=The MySQL clients and Maintenance Tools +IMAGE= +DEFSELECTION=Yes +filegroup0=Clients and Tools +COMMENT= +INCLUDEINBUILD=Yes +INSTALLATION=NEWERDATE +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + +[SetupTypeItem-Compact] +Comment= +item0=Grant Tables +item1=Clients and Tools +item2=Servers +item3=Documentation +Descrip= +DisplayText= + +[SetupTypeItem-Custom] +Comment= +item0=Development +item1=Grant Tables +item2=Clients and Tools +item3=Servers +Descrip= +item4=Documentation +DisplayText= + +[Info] +Type=CompDef +Version=1.00.000 +Name= + +[SetupTypeItem-Typical] +Comment= +item0=Development +item1=Grant Tables +item2=Clients and Tools +item3=Servers +Descrip= +item4=Documentation +DisplayText= + +[Documentation] +required0=Servers +SELECTED=Yes +FILENEED=HIGHLYRECOMMENDED +required1=Grant Tables +HTTPLOCATION= +STATUS=The MySQL Documentation with different formats +UNINSTALLABLE=Yes +TARGET= +FTPLOCATION= +VISIBLE=Yes +DESCRIPTION=The MySQL Documentation with different formats +DISPLAYTEXT=The MySQL Documentation with different formats +IMAGE= +DEFSELECTION=Yes +filegroup0=Documentation +COMMENT= +INCLUDEINBUILD=Yes +INSTALLATION=ALWAYSOVERWRITE +COMPRESSIFSEPARATE=No +MISC= +ENCRYPT=No +DISK=ANYDISK +TARGETDIRCDROM= +PASSWORD= +TARGETHIDDEN=General Application Destination + diff --git a/VC++Files/InstallShield/3.23.XXcom/Component Definitions/Default.fgl b/VC++Files/InstallShield/3.23.XXcom/Component Definitions/Default.fgl new file mode 100644 index 00000000000..4e20dcea4ab --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/Component Definitions/Default.fgl @@ -0,0 +1,42 @@ +[\] +DISPLAYTEXT=Common Files Folder +TYPE=TEXTSUBFIXED +fulldirectory= + +[\] +DISPLAYTEXT=Windows System Folder +TYPE=TEXTSUBFIXED +fulldirectory= + +[USERDEFINED] +DISPLAYTEXT=Script-defined Folders +TYPE=USERSTART +fulldirectory= + +[] +DISPLAYTEXT=Program Files Folder +SubDir0=\ +TYPE=TEXTSUBFIXED +fulldirectory= + +[] +DISPLAYTEXT=General Application Destination +TYPE=TEXTSUBFIXED +fulldirectory= + +[] +DISPLAYTEXT=Windows Operating System +SubDir0=\ +TYPE=TEXTSUBFIXED +fulldirectory= + +[TopDir] +SubDir0= +SubDir1= +SubDir2= +SubDir3=USERDEFINED + +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XXcom/File Groups/Clients and Tools.fgl b/VC++Files/InstallShield/3.23.XXcom/File Groups/Clients and Tools.fgl new file mode 100644 index 00000000000..7f30ff9f64b --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/File Groups/Clients and Tools.fgl @@ -0,0 +1,35 @@ +[bin] +file15=C:\mysql\bin\pack_isam.exe +file16=C:\mysql\bin\perror.exe +file0=C:\mysql\bin\isamchk.exe +file17=C:\mysql\bin\replace.exe +file1=C:\mysql\bin\myisamchk.exe +file18=C:\mysql\bin\winmysqladmin.cnt +file2=C:\mysql\bin\myisamlog.exe +file19=C:\mysql\bin\winmysqladmin.exe +file3=C:\mysql\bin\myisampack.exe +file4=C:\mysql\bin\mysql.exe +file5=C:\mysql\bin\mysqladmin.exe +file6=C:\mysql\bin\mysqlbinlog.exe +file7=C:\mysql\bin\mysqlc.exe +file8=C:\mysql\bin\mysqlcheck.exe +file9=C:\mysql\bin\mysqldump.exe +file20=C:\mysql\bin\WINMYSQLADMIN.HLP +file21=C:\mysql\bin\cygwinb19.dll +file10=C:\mysql\bin\mysqlimport.exe +fulldirectory= +file22=C:\mysql\bin\libmySQL.dll +file11=C:\mysql\bin\MySqlManager.exe +file23=C:\mysql\bin\my_print_defaults.exe +file12=C:\mysql\bin\mysqlshow.exe +file24=C:\mysql\bin\comp-err.exe +file13=C:\mysql\bin\mysqlshutdown.exe +file14=C:\mysql\bin\mysqlwatch.exe + +[TopDir] +SubDir0=bin + +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XXcom/File Groups/Default.fdf b/VC++Files/InstallShield/3.23.XXcom/File Groups/Default.fdf new file mode 100644 index 00000000000..282fae9d19b --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/File Groups/Default.fdf @@ -0,0 +1,82 @@ +[FileGroups] +group0=Development +group1=Grant Tables +group2=Clients and Tools +group3=Servers +group4=Documentation + +[Development] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM= +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + +[Grant Tables] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM= +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + +[Servers] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM= +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + +[Clients and Tools] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM=0000000000000000 +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + +[Info] +Type=FileGrp +Version=1.00.000 +Name= + +[Documentation] +SELFREGISTERING=No +HTTPLOCATION= +LANGUAGE= +OPERATINGSYSTEM= +FTPLOCATION= +FILETYPE=No +INFOTYPE=Standard +COMMENT= +COMPRESS=Yes +COMPRESSDLL= +POTENTIALLY=No +MISC= + diff --git a/VC++Files/InstallShield/3.23.XXcom/File Groups/Default.fgl b/VC++Files/InstallShield/3.23.XXcom/File Groups/Default.fgl new file mode 100644 index 00000000000..94344a6ff69 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/File Groups/Default.fgl @@ -0,0 +1,4 @@ +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XXcom/File Groups/Development.fgl b/VC++Files/InstallShield/3.23.XXcom/File Groups/Development.fgl new file mode 100644 index 00000000000..a1cf53f880a --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/File Groups/Development.fgl @@ -0,0 +1,190 @@ +[bench\Data\Wisconsin] +file0=C:\mysql\bench\Data\Wisconsin\onek.data +file1=C:\mysql\bench\Data\Wisconsin\tenk.data +fulldirectory= + +[lib\debug] +file0=C:\mysql\lib\debug\libmySQL.dll +file1=C:\mysql\lib\debug\libmySQL.lib +file2=C:\mysql\lib\debug\mysqlclient.lib +file3=C:\mysql\lib\debug\zlib.lib +fulldirectory= + +[bench\output] +fulldirectory= + +[examples\libmysqltest] +file0=C:\mysql\examples\libmysqltest\myTest.c +file1=C:\mysql\examples\libmysqltest\myTest.dsp +file2=C:\mysql\examples\libmysqltest\myTest.dsw +file3=C:\mysql\examples\libmysqltest\myTest.exe +file4=C:\mysql\examples\libmysqltest\myTest.mak +file5=C:\mysql\examples\libmysqltest\myTest.ncb +file6=C:\mysql\examples\libmysqltest\myTest.opt +file7=C:\mysql\examples\libmysqltest\readme +fulldirectory= + +[include] +file0=C:\mysql\include\raid.h +file1=C:\mysql\include\errmsg.h +file2=C:\mysql\include\Libmysql.def +file3=C:\mysql\include\m_ctype.h +file4=C:\mysql\include\m_string.h +file5=C:\mysql\include\my_list.h +file6=C:\mysql\include\my_pthread.h +file7=C:\mysql\include\my_sys.h +file8=C:\mysql\include\mysql.h +file9=C:\mysql\include\mysql_com.h +file10=C:\mysql\include\mysql_version.h +fulldirectory= +file11=C:\mysql\include\mysqld_error.h +file12=C:\mysql\include\dbug.h +file13=C:\mysql\include\my_global.h +file14=C:\mysql\include\config-win.h + +[examples] +SubDir0=examples\libmysqltest +SubDir1=examples\tests +fulldirectory= + +[lib\opt] +file0=C:\mysql\lib\opt\libmySQL.dll +file1=C:\mysql\lib\opt\libmySQL.lib +file2=C:\mysql\lib\opt\mysqlclient.lib +file3=C:\mysql\lib\opt\zlib.lib +fulldirectory= + +[bench\Data] +SubDir0=bench\Data\ATIS +SubDir1=bench\Data\Wisconsin +fulldirectory= + +[bench\limits] +file15=C:\mysql\bench\limits\pg.comment +file16=C:\mysql\bench\limits\solid.cfg +file0=C:\mysql\bench\limits\access.cfg +file17=C:\mysql\bench\limits\solid-nt4.cfg +file1=C:\mysql\bench\limits\access.comment +file18=C:\mysql\bench\limits\sybase.cfg +file2=C:\mysql\bench\limits\Adabas.cfg +file3=C:\mysql\bench\limits\Adabas.comment +file4=C:\mysql\bench\limits\Db2.cfg +file5=C:\mysql\bench\limits\empress.cfg +file6=C:\mysql\bench\limits\empress.comment +file7=C:\mysql\bench\limits\Informix.cfg +file8=C:\mysql\bench\limits\Informix.comment +file9=C:\mysql\bench\limits\msql.cfg +file10=C:\mysql\bench\limits\ms-sql.cfg +fulldirectory= +file11=C:\mysql\bench\limits\Ms-sql65.cfg +file12=C:\mysql\bench\limits\mysql.cfg +file13=C:\mysql\bench\limits\oracle.cfg +file14=C:\mysql\bench\limits\pg.cfg + +[TopDir] +SubDir0=bench +SubDir1=examples +SubDir2=include +SubDir3=lib +SubDir4=scripts + +[bench] +file15=C:\mysql\bench\test-create +file16=C:\mysql\bench\test-insert +file0=C:\mysql\bench\uname.bat +file17=C:\mysql\bench\test-select +file1=C:\mysql\bench\compare-results +file18=C:\mysql\bench\test-wisconsin +file2=C:\mysql\bench\copy-db +file19=C:\mysql\bench\bench-init.pl +file3=C:\mysql\bench\crash-me +file4=C:\mysql\bench\example.bat +file5=C:\mysql\bench\print-limit-table +file6=C:\mysql\bench\pwd.bat +file7=C:\mysql\bench\Readme +SubDir0=bench\Data +file8=C:\mysql\bench\run.bat +SubDir1=bench\limits +file9=C:\mysql\bench\run-all-tests +SubDir2=bench\output +file10=C:\mysql\bench\server-cfg +fulldirectory= +file11=C:\mysql\bench\test-alter-table +file12=C:\mysql\bench\test-ATIS +file13=C:\mysql\bench\test-big-tables +file14=C:\mysql\bench\test-connect + +[examples\tests] +file15=C:\mysql\examples\tests\lock_test.res +file16=C:\mysql\examples\tests\mail_to_db.pl +file0=C:\mysql\examples\tests\unique_users.tst +file17=C:\mysql\examples\tests\table_types.pl +file1=C:\mysql\examples\tests\auto_increment.tst +file18=C:\mysql\examples\tests\test_delayed_insert.pl +file2=C:\mysql\examples\tests\big_record.pl +file19=C:\mysql\examples\tests\udf_test +file3=C:\mysql\examples\tests\big_record.res +file4=C:\mysql\examples\tests\czech-sorting +file5=C:\mysql\examples\tests\deadlock-script.pl +file6=C:\mysql\examples\tests\export.pl +file7=C:\mysql\examples\tests\fork_test.pl +file8=C:\mysql\examples\tests\fork2_test.pl +file9=C:\mysql\examples\tests\fork3_test.pl +file20=C:\mysql\examples\tests\udf_test.res +file21=C:\mysql\examples\tests\auto_increment.res +file10=C:\mysql\examples\tests\function.res +fulldirectory= +file11=C:\mysql\examples\tests\function.tst +file12=C:\mysql\examples\tests\grant.pl +file13=C:\mysql\examples\tests\grant.res +file14=C:\mysql\examples\tests\lock_test.pl + +[bench\Data\ATIS] +file26=C:\mysql\bench\Data\ATIS\stop1.txt +file15=C:\mysql\bench\Data\ATIS\flight_class.txt +file27=C:\mysql\bench\Data\ATIS\time_interval.txt +file16=C:\mysql\bench\Data\ATIS\flight_day.txt +file0=C:\mysql\bench\Data\ATIS\transport.txt +file28=C:\mysql\bench\Data\ATIS\time_zone.txt +file17=C:\mysql\bench\Data\ATIS\flight_fare.txt +file1=C:\mysql\bench\Data\ATIS\airline.txt +file29=C:\mysql\bench\Data\ATIS\aircraft.txt +file18=C:\mysql\bench\Data\ATIS\food_service.txt +file2=C:\mysql\bench\Data\ATIS\airport.txt +file19=C:\mysql\bench\Data\ATIS\ground_service.txt +file3=C:\mysql\bench\Data\ATIS\airport_service.txt +file4=C:\mysql\bench\Data\ATIS\city.txt +file5=C:\mysql\bench\Data\ATIS\class_of_service.txt +file6=C:\mysql\bench\Data\ATIS\code_description.txt +file7=C:\mysql\bench\Data\ATIS\compound_class.txt +file8=C:\mysql\bench\Data\ATIS\connect_leg.txt +file9=C:\mysql\bench\Data\ATIS\date_day.txt +file20=C:\mysql\bench\Data\ATIS\month_name.txt +file21=C:\mysql\bench\Data\ATIS\restrict_carrier.txt +file10=C:\mysql\bench\Data\ATIS\day_name.txt +fulldirectory= +file22=C:\mysql\bench\Data\ATIS\restrict_class.txt +file11=C:\mysql\bench\Data\ATIS\dual_carrier.txt +file23=C:\mysql\bench\Data\ATIS\restriction.txt +file12=C:\mysql\bench\Data\ATIS\fare.txt +file24=C:\mysql\bench\Data\ATIS\state.txt +file13=C:\mysql\bench\Data\ATIS\fconnection.txt +file25=C:\mysql\bench\Data\ATIS\stop.txt +file14=C:\mysql\bench\Data\ATIS\flight.txt + +[General] +Type=FILELIST +Version=1.00.000 + +[scripts] +file0=C:\mysql\scripts\mysql_find_rows.pl +file1=C:\mysql\scripts\mysql_setpermission.pl +file2=C:\mysql\scripts\mysqlhotcopy.pl +file3=C:\mysql\scripts\Readme +fulldirectory= + +[lib] +SubDir0=lib\debug +SubDir1=lib\opt +fulldirectory= + diff --git a/VC++Files/InstallShield/3.23.XXcom/File Groups/Documentation.fgl b/VC++Files/InstallShield/3.23.XXcom/File Groups/Documentation.fgl new file mode 100644 index 00000000000..d36acb64538 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/File Groups/Documentation.fgl @@ -0,0 +1,98 @@ +[Docs\Flags] +file59=C:\mysql\Docs\Flags\romania.gif +file48=C:\mysql\Docs\Flags\kroatia.eps +file37=C:\mysql\Docs\Flags\iceland.gif +file26=C:\mysql\Docs\Flags\france.eps +file15=C:\mysql\Docs\Flags\china.gif +file49=C:\mysql\Docs\Flags\kroatia.gif +file38=C:\mysql\Docs\Flags\ireland.eps +file27=C:\mysql\Docs\Flags\france.gif +file16=C:\mysql\Docs\Flags\croatia.eps +file0=C:\mysql\Docs\Flags\usa.gif +file39=C:\mysql\Docs\Flags\ireland.gif +file28=C:\mysql\Docs\Flags\germany.eps +file17=C:\mysql\Docs\Flags\croatia.gif +file1=C:\mysql\Docs\Flags\argentina.gif +file29=C:\mysql\Docs\Flags\germany.gif +file18=C:\mysql\Docs\Flags\czech-republic.eps +file2=C:\mysql\Docs\Flags\australia.eps +file19=C:\mysql\Docs\Flags\czech-republic.gif +file3=C:\mysql\Docs\Flags\australia.gif +file80=C:\mysql\Docs\Flags\usa.eps +file4=C:\mysql\Docs\Flags\austria.eps +file81=C:\mysql\Docs\Flags\argentina.eps +file70=C:\mysql\Docs\Flags\spain.eps +file5=C:\mysql\Docs\Flags\austria.gif +file71=C:\mysql\Docs\Flags\spain.gif +file60=C:\mysql\Docs\Flags\russia.eps +file6=C:\mysql\Docs\Flags\brazil.eps +file72=C:\mysql\Docs\Flags\sweden.eps +file61=C:\mysql\Docs\Flags\russia.gif +file50=C:\mysql\Docs\Flags\latvia.eps +file7=C:\mysql\Docs\Flags\brazil.gif +file73=C:\mysql\Docs\Flags\sweden.gif +file62=C:\mysql\Docs\Flags\singapore.eps +file51=C:\mysql\Docs\Flags\latvia.gif +file40=C:\mysql\Docs\Flags\island.eps +file8=C:\mysql\Docs\Flags\bulgaria.eps +file74=C:\mysql\Docs\Flags\switzerland.eps +file63=C:\mysql\Docs\Flags\singapore.gif +file52=C:\mysql\Docs\Flags\netherlands.eps +file41=C:\mysql\Docs\Flags\island.gif +file30=C:\mysql\Docs\Flags\great-britain.eps +file9=C:\mysql\Docs\Flags\bulgaria.gif +file75=C:\mysql\Docs\Flags\switzerland.gif +file64=C:\mysql\Docs\Flags\south-africa.eps +file53=C:\mysql\Docs\Flags\netherlands.gif +file42=C:\mysql\Docs\Flags\israel.eps +file31=C:\mysql\Docs\Flags\great-britain.gif +file20=C:\mysql\Docs\Flags\denmark.eps +file76=C:\mysql\Docs\Flags\taiwan.eps +file65=C:\mysql\Docs\Flags\south-africa.gif +file54=C:\mysql\Docs\Flags\poland.eps +file43=C:\mysql\Docs\Flags\israel.gif +file32=C:\mysql\Docs\Flags\greece.eps +file21=C:\mysql\Docs\Flags\denmark.gif +file10=C:\mysql\Docs\Flags\canada.eps +fulldirectory= +file77=C:\mysql\Docs\Flags\taiwan.gif +file66=C:\mysql\Docs\Flags\south-africa1.eps +file55=C:\mysql\Docs\Flags\poland.gif +file44=C:\mysql\Docs\Flags\italy.eps +file33=C:\mysql\Docs\Flags\greece.gif +file22=C:\mysql\Docs\Flags\estonia.eps +file11=C:\mysql\Docs\Flags\canada.gif +file78=C:\mysql\Docs\Flags\ukraine.eps +file67=C:\mysql\Docs\Flags\south-africa1.gif +file56=C:\mysql\Docs\Flags\portugal.eps +file45=C:\mysql\Docs\Flags\italy.gif +file34=C:\mysql\Docs\Flags\hungary.eps +file23=C:\mysql\Docs\Flags\estonia.gif +file12=C:\mysql\Docs\Flags\chile.eps +file79=C:\mysql\Docs\Flags\ukraine.gif +file68=C:\mysql\Docs\Flags\south-korea.eps +file57=C:\mysql\Docs\Flags\portugal.gif +file46=C:\mysql\Docs\Flags\japan.eps +file35=C:\mysql\Docs\Flags\hungary.gif +file24=C:\mysql\Docs\Flags\finland.eps +file13=C:\mysql\Docs\Flags\chile.gif +file69=C:\mysql\Docs\Flags\south-korea.gif +file58=C:\mysql\Docs\Flags\romania.eps +file47=C:\mysql\Docs\Flags\japan.gif +file36=C:\mysql\Docs\Flags\iceland.eps +file25=C:\mysql\Docs\Flags\finland.gif +file14=C:\mysql\Docs\Flags\china.eps + +[Docs] +file0=C:\mysql\Docs\manual_toc.html +file1=C:\mysql\Docs\manual.html +SubDir0=Docs\Flags +fulldirectory= + +[TopDir] +SubDir0=Docs + +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XXcom/File Groups/Grant Tables.fgl b/VC++Files/InstallShield/3.23.XXcom/File Groups/Grant Tables.fgl new file mode 100644 index 00000000000..178065a7003 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/File Groups/Grant Tables.fgl @@ -0,0 +1,36 @@ +[data\test] +fulldirectory= + +[data\mysql] +file15=C:\mysql\data\mysql\func.frm +file16=C:\mysql\data\mysql\func.MYD +file0=C:\mysql\data\mysql\columns_priv.frm +file17=C:\mysql\data\mysql\func.MYI +file1=C:\mysql\data\mysql\columns_priv.MYD +file2=C:\mysql\data\mysql\columns_priv.MYI +file3=C:\mysql\data\mysql\db.frm +file4=C:\mysql\data\mysql\db.MYD +file5=C:\mysql\data\mysql\db.MYI +file6=C:\mysql\data\mysql\host.frm +file7=C:\mysql\data\mysql\host.MYD +file8=C:\mysql\data\mysql\host.MYI +file9=C:\mysql\data\mysql\tables_priv.frm +file10=C:\mysql\data\mysql\tables_priv.MYD +fulldirectory= +file11=C:\mysql\data\mysql\tables_priv.MYI +file12=C:\mysql\data\mysql\user.frm +file13=C:\mysql\data\mysql\user.MYD +file14=C:\mysql\data\mysql\user.MYI + +[TopDir] +SubDir0=data + +[data] +SubDir0=data\mysql +SubDir1=data\test +fulldirectory= + +[General] +Type=FILELIST +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XXcom/File Groups/Servers.fgl b/VC++Files/InstallShield/3.23.XXcom/File Groups/Servers.fgl new file mode 100644 index 00000000000..6f91a474d80 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/File Groups/Servers.fgl @@ -0,0 +1,183 @@ +[share\polish] +file0=C:\mysql\share\polish\errmsg.sys +file1=C:\mysql\share\polish\errmsg.txt +fulldirectory= + +[share\dutch] +file0=C:\mysql\share\dutch\errmsg.sys +file1=C:\mysql\share\dutch\errmsg.txt +fulldirectory= + +[share\spanish] +file0=C:\mysql\share\spanish\errmsg.sys +file1=C:\mysql\share\spanish\errmsg.txt +fulldirectory= + +[share\english] +file0=C:\mysql\share\english\errmsg.sys +file1=C:\mysql\share\english\errmsg.txt +fulldirectory= + +[bin] +file0=C:\mysql\bin\mysqld-opt.exe +file1=C:\mysql\bin\mysqld-max.exe +file2=C:\mysql\bin\mysqld-max-nt.exe +file3=C:\mysql\bin\mysqld-nt.exe +file4=C:\mysql\bin\mysqld.exe +fulldirectory= + +[share\korean] +file0=C:\mysql\share\korean\errmsg.sys +file1=C:\mysql\share\korean\errmsg.txt +fulldirectory= + +[share\charsets] +file15=C:\mysql\share\charsets\latin1.conf +file16=C:\mysql\share\charsets\latin2.conf +file0=C:\mysql\share\charsets\win1251ukr.conf +file17=C:\mysql\share\charsets\latin5.conf +file1=C:\mysql\share\charsets\cp1257.conf +file18=C:\mysql\share\charsets\Readme +file2=C:\mysql\share\charsets\croat.conf +file19=C:\mysql\share\charsets\swe7.conf +file3=C:\mysql\share\charsets\danish.conf +file4=C:\mysql\share\charsets\dec8.conf +file5=C:\mysql\share\charsets\dos.conf +file6=C:\mysql\share\charsets\estonia.conf +file7=C:\mysql\share\charsets\german1.conf +file8=C:\mysql\share\charsets\greek.conf +file9=C:\mysql\share\charsets\hebrew.conf +file20=C:\mysql\share\charsets\usa7.conf +file21=C:\mysql\share\charsets\win1250.conf +file10=C:\mysql\share\charsets\hp8.conf +fulldirectory= +file22=C:\mysql\share\charsets\win1251.conf +file11=C:\mysql\share\charsets\hungarian.conf +file23=C:\mysql\share\charsets\cp1251.conf +file12=C:\mysql\share\charsets\Index +file13=C:\mysql\share\charsets\koi8_ru.conf +file14=C:\mysql\share\charsets\koi8_ukr.conf + +[share\ukrainian] +file0=C:\mysql\share\ukrainian\errmsg.sys +file1=C:\mysql\share\ukrainian\errmsg.txt +fulldirectory= + +[share\hungarian] +file0=C:\mysql\share\hungarian\errmsg.sys +file1=C:\mysql\share\hungarian\errmsg.txt +fulldirectory= + +[share\german] +file0=C:\mysql\share\german\errmsg.sys +file1=C:\mysql\share\german\errmsg.txt +fulldirectory= + +[share\portuguese] +file0=C:\mysql\share\portuguese\errmsg.sys +file1=C:\mysql\share\portuguese\errmsg.txt +fulldirectory= + +[share\estonian] +file0=C:\mysql\share\estonian\errmsg.sys +file1=C:\mysql\share\estonian\errmsg.txt +fulldirectory= + +[share\romanian] +file0=C:\mysql\share\romanian\errmsg.sys +file1=C:\mysql\share\romanian\errmsg.txt +fulldirectory= + +[share\french] +file0=C:\mysql\share\french\errmsg.sys +file1=C:\mysql\share\french\errmsg.txt +fulldirectory= + +[share\swedish] +file0=C:\mysql\share\swedish\errmsg.sys +file1=C:\mysql\share\swedish\errmsg.txt +fulldirectory= + +[share\slovak] +file0=C:\mysql\share\slovak\errmsg.sys +file1=C:\mysql\share\slovak\errmsg.txt +fulldirectory= + +[share\greek] +file0=C:\mysql\share\greek\errmsg.sys +file1=C:\mysql\share\greek\errmsg.txt +fulldirectory= + +[TopDir] +file0=C:\mysql\my-small.cnf +file1=C:\mysql\my-large.cnf +file2=C:\mysql\my-medium.cnf +file3=C:\mysql\my-huge.cnf +SubDir0=bin +SubDir1=share + +[share] +SubDir8=share\hungarian +SubDir9=share\charsets +SubDir20=share\spanish +SubDir21=share\swedish +SubDir10=share\italian +SubDir22=share\ukrainian +SubDir11=share\japanese +SubDir12=share\korean +SubDir13=share\norwegian +SubDir14=share\norwegian-ny +SubDir15=share\polish +SubDir16=share\portuguese +SubDir0=share\czech +SubDir17=share\romanian +SubDir1=share\danish +SubDir18=share\russian +SubDir2=share\dutch +SubDir19=share\slovak +SubDir3=share\english +fulldirectory= +SubDir4=share\estonian +SubDir5=share\french +SubDir6=share\german +SubDir7=share\greek + +[share\norwegian-ny] +file0=C:\mysql\share\norwegian-ny\errmsg.sys +file1=C:\mysql\share\norwegian-ny\errmsg.txt +fulldirectory= + +[share\danish] +file0=C:\mysql\share\danish\errmsg.sys +file1=C:\mysql\share\danish\errmsg.txt +fulldirectory= + +[share\czech] +file0=C:\mysql\share\czech\errmsg.sys +file1=C:\mysql\share\czech\errmsg.txt +fulldirectory= + +[General] +Type=FILELIST +Version=1.00.000 + +[share\russian] +file0=C:\mysql\share\russian\errmsg.sys +file1=C:\mysql\share\russian\errmsg.txt +fulldirectory= + +[share\norwegian] +file0=C:\mysql\share\norwegian\errmsg.sys +file1=C:\mysql\share\norwegian\errmsg.txt +fulldirectory= + +[share\japanese] +file0=C:\mysql\share\japanese\errmsg.sys +file1=C:\mysql\share\japanese\errmsg.txt +fulldirectory= + +[share\italian] +file0=C:\mysql\share\italian\errmsg.sys +file1=C:\mysql\share\italian\errmsg.txt +fulldirectory= + diff --git a/VC++Files/InstallShield/3.23.XXcom/MySQL 3.23.com.ipr b/VC++Files/InstallShield/3.23.XXcom/MySQL 3.23.com.ipr new file mode 100644 index 00000000000..811d69717d8 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/MySQL 3.23.com.ipr @@ -0,0 +1,51 @@ +[Language] +LanguageSupport0=0009 + +[OperatingSystem] +OSSupport=0000000000010010 + +[Data] +CurrentMedia= +set_mifserial= +ProductName=MySQL Servers and Clients +CurrentComponentDef=Default.cdf +set_dlldebug=No +AppExe= +DevEnvironment=Microsoft Visual C++ 6 +set_mif=No +set_testmode=No +Instructions=Instructions.txt +EmailAddresss= +SummaryText= +Department= +Type=Database Application +Author= +HomeURL= +InstallRoot=C:\MySQL-Install\3.23.XXcom +set_level=Level 3 +InstallationGUID=40744a4d-efed-4cff-84a9-9e6389550f5c +Version=1.00.000 +set_miffile=Status.mif +set_args= +set_maxerr=50 +Notes=Notes.txt +CurrentFileGroupDef=Default.fdf +set_dllcmdline= +set_warnaserr=No +Copyright= +set_preproc= +Category= +CurrentPlatform= +set_compileb4build=No +set_crc=Yes +set_maxwarn=50 +Description=Description.txt +CompanyName=MySQL +CurrentLanguage=English + +[MediaInfo] + +[General] +Type=INSTALLMAIN +Version=1.10.000 + diff --git a/VC++Files/InstallShield/3.23.XXcom/Registry Entries/Default.rge b/VC++Files/InstallShield/3.23.XXcom/Registry Entries/Default.rge new file mode 100644 index 00000000000..537dfd82e48 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/Registry Entries/Default.rge @@ -0,0 +1,4 @@ +[General] +Type=REGISTRYDATA +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.dbg b/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.dbg new file mode 100644 index 0000000000000000000000000000000000000000..0c6d4e6b70812d069322e88155868913fc543e33 GIT binary patch literal 28458 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 literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.ino b/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.ino new file mode 100644 index 0000000000000000000000000000000000000000..204d8ea0f364524a444de8aa4c839fbdfb40413c GIT binary patch literal 58611 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 z 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 literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.ins b/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.ins new file mode 100644 index 0000000000000000000000000000000000000000..759009b5c8462f5f1b617fb9f202c2e638ce4bc4 GIT binary patch literal 57122 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 U?Y7{S!vK%H{K_l&d*#Ca2lRel4gdfE literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.obs b/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.obs new file mode 100644 index 0000000000000000000000000000000000000000..5fcfcb62c4e70338ce55aab3c89149f351d7f4c1 GIT binary patch literal 65611 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 MQd<)aB(wnj4?UUG^8f$< literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.rul b/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.rul new file mode 100644 index 00000000000..0db8417a62c --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/Script Files/Setup.rul @@ -0,0 +1,641 @@ + +//////////////////////////////////////////////////////////////////////////////// +// +// IIIIIII SSSSSS +// II SS InstallShield (R) +// II SSSSSS (c) 1996-1997, InstallShield Software Corporation +// II SS (c) 1990-1996, InstallShield Corporation +// IIIIIII SSSSSS All Rights Reserved. +// +// +// This code is generated as a starting setup template. You should +// modify it to provide all necessary steps for your setup. +// +// +// File Name: Setup.rul +// +// Description: InstallShield script +// +// Comments: This template script performs a basic setup on a +// Windows 95 or Windows NT 4.0 platform. With minor +// modifications, this template can be adapted to create +// new, customized setups. +// +//////////////////////////////////////////////////////////////////////////////// + + + // Include header file +#include "sdlang.h" +#include "sddialog.h" + +////////////////////// string defines //////////////////////////// + +#define UNINST_LOGFILE_NAME "Uninst.isu" + +//////////////////// installation declarations /////////////////// + + // ----- DLL prototypes ----- + + + // your DLL prototypes + + + // ---- script prototypes ----- + + // generated + prototype ShowDialogs(); + prototype MoveFileData(); + prototype HandleMoveDataError( NUMBER ); + prototype ProcessBeforeDataMove(); + prototype ProcessAfterDataMove(); + prototype SetupRegistry(); + prototype SetupFolders(); + prototype CleanUpInstall(); + prototype SetupInstall(); + prototype SetupScreen(); + prototype CheckRequirements(); + prototype DialogShowSdWelcome(); + prototype DialogShowSdShowInfoList(); + prototype DialogShowSdAskDestPath(); + prototype DialogShowSdSetupType(); + prototype DialogShowSdComponentDialog2(); + prototype DialogShowSdFinishReboot(); + + // your prototypes + + + // ----- global variables ------ + + // generated + BOOL bWinNT, bIsShellExplorer, bInstallAborted, bIs32BitSetup; + STRING svDir; + STRING svName, svCompany, svSerial; + STRING szAppPath; + STRING svSetupType; + + + // your global variables + + +/////////////////////////////////////////////////////////////////////////////// +// +// MAIN PROGRAM +// +// The setup begins here by hiding the visible setup +// window. This is done to allow all the titles, images, etc. to +// be established before showing the main window. The following +// logic then performs the setup in a series of steps. +// +/////////////////////////////////////////////////////////////////////////////// +program + Disable( BACKGROUND ); + + CheckRequirements(); + + SetupInstall(); + + SetupScreen(); + + if (ShowDialogs()<0) goto end_install; + + if (ProcessBeforeDataMove()<0) goto end_install; + + if (MoveFileData()<0) goto end_install; + + if (ProcessAfterDataMove()<0) goto end_install; + + if (SetupRegistry()<0) goto end_install; + + if (SetupFolders()<0) goto end_install; + + + end_install: + + CleanUpInstall(); + + // If an unrecoverable error occurred, clean up the partial installation. + // Otherwise, exit normally. + + if (bInstallAborted) then + abort; + endif; + +endprogram + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: ShowDialogs // +// // +// Purpose: This function manages the display and navigation // +// the standard dialogs that exist in a setup. // +// // +/////////////////////////////////////////////////////////////////////////////// +function ShowDialogs() + NUMBER nResult; + begin + + Dlg_Start: + // beginning of dialogs label + + Dlg_SdWelcome: + nResult = DialogShowSdWelcome(); + if (nResult = BACK) goto Dlg_Start; + + Dlg_SdShowInfoList: + nResult = DialogShowSdShowInfoList(); + if (nResult = BACK) goto Dlg_SdWelcome; + + Dlg_SdAskDestPath: + nResult = DialogShowSdAskDestPath(); + if (nResult = BACK) goto Dlg_SdShowInfoList; + + Dlg_SdSetupType: + nResult = DialogShowSdSetupType(); + if (nResult = BACK) goto Dlg_SdAskDestPath; + + Dlg_SdComponentDialog2: + if ((nResult = BACK) && (svSetupType != "Custom") && (svSetupType != "")) then + goto Dlg_SdSetupType; + endif; + nResult = DialogShowSdComponentDialog2(); + if (nResult = BACK) goto Dlg_SdSetupType; + + return 0; + + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: ProcessBeforeDataMove // +// // +// Purpose: This function performs any necessary operations prior to the // +// actual data move operation. // +// // +/////////////////////////////////////////////////////////////////////////////// +function ProcessBeforeDataMove() + STRING svLogFile; + NUMBER nResult; + begin + + InstallationInfo( @COMPANY_NAME, @PRODUCT_NAME, @PRODUCT_VERSION, @PRODUCT_KEY ); + + svLogFile = UNINST_LOGFILE_NAME; + + nResult = DeinstallStart( svDir, svLogFile, @UNINST_KEY, 0 ); + if (nResult < 0) then + MessageBox( @ERROR_UNINSTSETUP, WARNING ); + endif; + + szAppPath = TARGETDIR; // TODO : if your application .exe is in a subdir of TARGETDIR then add subdir + + if ((bIs32BitSetup) && (bIsShellExplorer)) then + RegDBSetItem( REGDB_APPPATH, szAppPath ); + RegDBSetItem( REGDB_APPPATH_DEFAULT, szAppPath ^ @PRODUCT_KEY ); + RegDBSetItem( REGDB_UNINSTALL_NAME, @UNINST_DISPLAY_NAME ); + endif; + + // TODO : update any items you want to process before moving the data + // + + return 0; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: MoveFileData // +// // +// Purpose: This function handles the data movement for // +// the setup. // +// // +/////////////////////////////////////////////////////////////////////////////// +function MoveFileData() + NUMBER nResult, nDisk; + begin + + nDisk = 1; + SetStatusWindow( 0, "" ); + Disable( DIALOGCACHE ); + Enable( STATUS ); + StatusUpdate( ON, 100 ); + nResult = ComponentMoveData( MEDIA, nDisk, 0 ); + + HandleMoveDataError( nResult ); + + Disable( STATUS ); + + return nResult; + + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: HandleMoveDataError // +// // +// Purpose: This function handles the error (if any) during the move data // +// operation. // +// // +/////////////////////////////////////////////////////////////////////////////// +function HandleMoveDataError( nResult ) + STRING szErrMsg, svComponent , svFileGroup , svFile; + begin + + svComponent = ""; + svFileGroup = ""; + svFile = ""; + + switch (nResult) + case 0: + return 0; + default: + ComponentError ( MEDIA , svComponent , svFileGroup , svFile , nResult ); + szErrMsg = @ERROR_MOVEDATA + "\n\n" + + @ERROR_COMPONENT + " " + svComponent + "\n" + + @ERROR_FILEGROUP + " " + svFileGroup + "\n" + + @ERROR_FILE + " " + svFile; + SprintfBox( SEVERE, @TITLE_CAPTIONBAR, szErrMsg, nResult ); + bInstallAborted = TRUE; + return nResult; + endswitch; + + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: ProcessAfterDataMove // +// // +// Purpose: This function performs any necessary operations needed after // +// all data has been moved. // +// // +/////////////////////////////////////////////////////////////////////////////// +function ProcessAfterDataMove() + begin + + // TODO : update self-registered files and other processes that + // should be performed after the data has been moved. + + + return 0; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: SetupRegistry // +// // +// Purpose: This function makes the registry entries for this setup. // +// // +/////////////////////////////////////////////////////////////////////////////// +function SetupRegistry() + NUMBER nResult; + + begin + + // TODO : Add all your registry entry keys here + // + // + // RegDBCreateKeyEx, RegDBSetKeyValueEx.... + // + + nResult = CreateRegistrySet( "" ); + + return nResult; + end; + +/////////////////////////////////////////////////////////////////////////////// +// +// Function: SetupFolders +// +// Purpose: This function creates all the folders and shortcuts for the +// setup. This includes program groups and items for Windows 3.1. +// +/////////////////////////////////////////////////////////////////////////////// +function SetupFolders() + NUMBER nResult; + + begin + + + // TODO : Add all your folder (program group) along with shortcuts (program items) + // + // + // CreateProgramFolder, AddFolderIcon.... + // + + nResult = CreateShellObjects( "" ); + + return nResult; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: CleanUpInstall // +// // +// Purpose: This cleans up the setup. Anything that should // +// be released or deleted at the end of the setup should // +// be done here. // +// // +/////////////////////////////////////////////////////////////////////////////// +function CleanUpInstall() + begin + + + if (bInstallAborted) then + return 0; + endif; + + DialogShowSdFinishReboot(); + + if (BATCH_INSTALL) then // ensure locked files are properly written + CommitSharedFiles(0); + endif; + + return 0; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: SetupInstall // +// // +// Purpose: This will setup the installation. Any general initialization // +// needed for the installation should be performed here. // +// // +/////////////////////////////////////////////////////////////////////////////// +function SetupInstall() + begin + + Enable( CORECOMPONENTHANDLING ); + + bInstallAborted = FALSE; + + if (bIs32BitSetup) then + svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME ^ @PRODUCT_NAME; + else + svDir = "C:\\mysql"; //PROGRAMFILES ^ @COMPANY_NAME16 ^ @PRODUCT_NAME16; // use shorten names + endif; + + TARGETDIR = svDir; + + SdProductName( @PRODUCT_NAME ); + + Enable( DIALOGCACHE ); + + return 0; + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: SetupScreen // +// // +// Purpose: This function establishes the screen look. This includes // +// colors, fonts, and text to be displayed. // +// // +/////////////////////////////////////////////////////////////////////////////// +function SetupScreen() + begin + + Enable( FULLWINDOWMODE ); + Enable( INDVFILESTATUS ); + SetTitle( @TITLE_MAIN, 24, WHITE ); + + SetTitle( @TITLE_CAPTIONBAR, 0, BACKGROUNDCAPTION ); // Caption bar text. + + Enable( BACKGROUND ); + + Delay( 1 ); + end; + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: CheckRequirements // +// // +// Purpose: This function checks all minimum requirements for the // +// application being installed. If any fail, then the user // +// is informed and the setup is terminated. // +// // +/////////////////////////////////////////////////////////////////////////////// +function CheckRequirements() + NUMBER nvDx, nvDy, nvResult; + STRING svResult; + + begin + + bWinNT = FALSE; + bIsShellExplorer = FALSE; + + // Check screen resolution. + GetExtents( nvDx, nvDy ); + + if (nvDy < 480) then + MessageBox( @ERROR_VGARESOLUTION, WARNING ); + abort; + endif; + + // set 'setup' operation mode + bIs32BitSetup = TRUE; + GetSystemInfo( ISTYPE, nvResult, svResult ); + if (nvResult = 16) then + bIs32BitSetup = FALSE; // running 16-bit setup + return 0; // no additional information required + endif; + + // --- 32-bit testing after this point --- + + // Determine the target system's operating system. + GetSystemInfo( OS, nvResult, svResult ); + + if (nvResult = IS_WINDOWSNT) then + // Running Windows NT. + bWinNT = TRUE; + + // Check to see if the shell being used is EXPLORER shell. + if (GetSystemInfo( OSMAJOR, nvResult, svResult ) = 0) then + if (nvResult >= 4) then + bIsShellExplorer = TRUE; + endif; + endif; + + elseif (nvResult = IS_WINDOWS95 ) then + bIsShellExplorer = TRUE; + + endif; + +end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdWelcome // +// // +// Purpose: This function handles the standard welcome dialog. // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdWelcome() + NUMBER nResult; + STRING szTitle, szMsg; + begin + + szTitle = ""; + szMsg = ""; + nResult = SdWelcome( szTitle, szMsg ); + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdShowInfoList // +// // +// Purpose: This function displays the general information list dialog. // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdShowInfoList() + NUMBER nResult; + LIST list; + STRING szTitle, szMsg, szFile; + begin + + szFile = SUPPORTDIR ^ "infolist.txt"; + + list = ListCreate( STRINGLIST ); + ListReadFromFile( list, szFile ); + szTitle = ""; + szMsg = " "; + nResult = SdShowInfoList( szTitle, szMsg, list ); + + ListDestroy( list ); + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdAskDestPath // +// // +// Purpose: This function asks the user for the destination directory. // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdAskDestPath() + NUMBER nResult; + STRING szTitle, szMsg; + begin + + szTitle = ""; + szMsg = ""; + nResult = SdAskDestPath( szTitle, szMsg, svDir, 0 ); + + TARGETDIR = svDir; + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdSetupType // +// // +// Purpose: This function displays the standard setup type dialog. // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdSetupType() + NUMBER nResult, nType; + STRING szTitle, szMsg; + begin + + switch (svSetupType) + case "Typical": + nType = TYPICAL; + case "Custom": + nType = CUSTOM; + case "Compact": + nType = COMPACT; + case "": + svSetupType = "Typical"; + nType = TYPICAL; + endswitch; + + szTitle = ""; + szMsg = ""; + nResult = SetupType( szTitle, szMsg, "", nType, 0 ); + + switch (nResult) + case COMPACT: + svSetupType = "Compact"; + case TYPICAL: + svSetupType = "Typical"; + case CUSTOM: + svSetupType = "Custom"; + endswitch; + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdComponentDialog2 // +// // +// Purpose: This function displays the custom component dialog. // +// // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdComponentDialog2() + NUMBER nResult; + STRING szTitle, szMsg; + begin + + if ((svSetupType != "Custom") && (svSetupType != "")) then + return 0; + endif; + + szTitle = ""; + szMsg = ""; + nResult = SdComponentDialog2( szTitle, szMsg, svDir, "" ); + + return nResult; + end; + + +/////////////////////////////////////////////////////////////////////////////// +// // +// Function: DialogShowSdFinishReboot // +// // +// Purpose: This function will show the last dialog of the product. // +// It will allow the user to reboot and/or show some readme text. // +// // +/////////////////////////////////////////////////////////////////////////////// +function DialogShowSdFinishReboot() + NUMBER nResult, nDefOptions; + STRING szTitle, szMsg1, szMsg2, szOption1, szOption2; + NUMBER bOpt1, bOpt2; + begin +/* + if (!BATCH_INSTALL) then + bOpt1 = FALSE; + bOpt2 = FALSE; + szMsg1 = ""; + szMsg2 = ""; + szOption1 = ""; + szOption2 = ""; + nResult = SdFinish( szTitle, szMsg1, szMsg2, szOption1, szOption2, bOpt1, bOpt2 ); + return 0; + endif; + + nDefOptions = SYS_BOOTMACHINE; + szTitle = ""; + szMsg1 = ""; + szMsg2 = ""; + nResult = SdFinishReboot( szTitle, szMsg1, nDefOptions, szMsg2, 0 ); +*/ + return nResult; + end; + + // --- include script file section --- + +#include "sddialog.rul" + + + diff --git a/VC++Files/InstallShield/3.23.XXcom/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt b/VC++Files/InstallShield/3.23.XXcom/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt new file mode 100644 index 00000000000..2f561d29d81 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/Setup Files/Compressed Files/Language Independent/OS Independent/infolist.txt @@ -0,0 +1,24 @@ +This is a release of MySQL 3.23.56 for Win32. + +NOTE: If you install MySQL in a folder other than +C:\MYSQL or you intend to start MySQL on NT/Win2000 +as a service, you must create a file named C:\MY.CNF +or \Windows\my.ini or \winnt\my.ini with the following +information:: + +[mysqld] +basedir=E:/installation-path/ +datadir=E:/data-path/ + +After your have installed MySQL, the installation +directory which contains the files named 'my-size.cnf'. +You can use this as a starting point for your own +C:\my.cnf file. + +If you have any problems, you can mail them to +win32@lists.mysql.com after you have consulted the +MySQL manual and the MySQL mailing list archive +(http://www.mysql.com/documentation/index.html) + +On behalf of the MySQL AB gang, +Michael Widenius \ No newline at end of file diff --git a/VC++Files/InstallShield/3.23.XXcom/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP b/VC++Files/InstallShield/3.23.XXcom/Setup Files/Uncompressed Files/Language Independent/OS Independent/SETUP.BMP new file mode 100644 index 0000000000000000000000000000000000000000..3229d50c9bfcabefefb1341fda098d20bcc734b1 GIT binary patch literal 15694 zcmeI3JB%Ae7{@=K-(K76_xXH&Oi7uF4k@AsrK3$jjnYv@G&D%0il|5m3XnjGA{wMf zL_$gf5>dL)5Cs$g3Mf1j1%y!e9<#Hv>lu6R&bNC-MzTHL8PERqKl43y_U_f!UVjC+ zyj%fz32PtY>kWLBpuxxK?R+3FJjmtqYZu|WZ*RcE`?ulUHv!&%s|Q!#R`B6F=isCF z&ckO{FTkx&F2PqfFT>ZjuE4!J*Wu?M?!xcCK7eOWpTLDLet}DOegpX60rajt1ohF6 zaPHGbaQ@~`aPiB>aQT}jaOK_~aQ*&YaO3-@aQo3Sxcm4Yc<|@H@Z|6R;Q90C0`lVh zg#s@W$Xx-Iz0}KVrP>I(*#|g5PdLJF9h?MS&x3RaoaIXA2p4(N7hE}BaV%I}cL;-qtVlj;-e}&Za^l2$Z)OHw_D6{(`O=TtSF@fhgG48#CUZ5I z4yV%;XV*{|iEYl7X*P&l@o}PΞYl3Pc*AWK<5_&B8evjnkZ9&L1hLEKZN3FPHtC zgCT>?5;ECe7}VFS7UP5EU_2Y7IJ*Y3T#lkl%-NFG1}ZO3c5Stn=?H{M=3C@t0UsXOLL1Rv?)sh2j;#7Uc!oV)f#O2xiD zE2oZ)!+pu!@cmHdAUoAF7Leq`#FY7(+4U4TM^10OLp^0dM#+bYeSNGaI{~k~3kxqt zxl-$WcbsD24Qp)i^?|)U>sU}>yL9MSog#v;aGGX!;QEO&v7T$E zPaHT!&ae?^&Irmrv!Gj^)NWj_3ukc$>f{1s;@8{c_Q}f`(v2f; zUxCan!Bk?WB!Y&qpi!98O1nSy9UOSbikxd5l;a=PPBqbiXYHqRLtOqP!C}X zK_KR|rPpbbhqcYmO1kKs*y@YnEHxUu?T5ZRHfe_@K_v>4g>X{t!`VcwoX&l0*buYL zn%>4Ng0n<6OtGf9@d+6{D$vor5PL@#4v5;II~yzF*h(tZX=1KqrA7tl8DQdzn=f@$ z$CtBo2@`Fq~%*lrvfEPylc z_#-C8OvNxZ6C3-JN%Hw7~(%ITmJ|$;bPq z7noXZ6%3i4bD@tEAR!PIiA;39M0e2K&!p`kHC|5(v1i{ zCh`{Wwwz8w)gu~O*Tz2|&Y2UpU!4I5U6R*zvS2xL;!cfgo(R+Hl8WFo)1Fw1gtPi^BL1w{geV-aho6HBV0Tk*Q3+gPELuAnYZSh8#I@A1)afyR literal 0 HcmV?d00001 diff --git a/VC++Files/InstallShield/3.23.XXcom/Shell Objects/Default.shl b/VC++Files/InstallShield/3.23.XXcom/Shell Objects/Default.shl new file mode 100644 index 00000000000..187cb651307 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/Shell Objects/Default.shl @@ -0,0 +1,12 @@ +[Data] +Folder3= +Group0=Main +Group1=Startup +Folder0= +Folder1= +Folder2= + +[Info] +Type=ShellObject +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XXcom/String Tables/0009-English/value.shl b/VC++Files/InstallShield/3.23.XXcom/String Tables/0009-English/value.shl new file mode 100644 index 00000000000..dd998365667 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/String Tables/0009-English/value.shl @@ -0,0 +1,23 @@ +[Data] +TITLE_MAIN=MySQL Commercial Servers and Clients 3.23.56 +ERROR_COMPONENT=Component: +COMPANY_NAME=MySQL AB +COMPANY_NAME16=Company +ERROR_FILEGROUP=File Group: +ERROR_MOVEDATA=An error occurred during the move data process: %d +PRODUCT_VERSION=3.23.56 +UNINST_KEY=MySQL Commercial Servers and Clients 3.23.56 +TITLE_CAPTIONBAR=MySQL Commercial Servers and Clients 3.23.56 Setup +PRODUCT_NAME16=Product +ERROR_FILE=File: +ERROR_VGARESOLUTION=This program requires VGA or better resolution. +PRODUCT_KEY=yourapp.Exe +UNINST_DISPLAY_NAME=MySQL Commercial Servers and Clients 3.23.56 +ERROR_UNINSTSETUP=unInstaller setup failed to initialize. You may not be able to uninstall this product. +PRODUCT_NAME=MySQL Commercial Servers and Clients 3.23.56 + +[General] +Language=0009 +Type=STRINGTABLESPECIFIC +Version=1.00.000 + diff --git a/VC++Files/InstallShield/3.23.XXcom/String Tables/Default.shl b/VC++Files/InstallShield/3.23.XXcom/String Tables/Default.shl new file mode 100644 index 00000000000..f197667992e --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/String Tables/Default.shl @@ -0,0 +1,74 @@ +[TITLE_MAIN] +Comment= + +[ERROR_COMPONENT] +Comment= + +[COMPANY_NAME] +Comment= + +[COMPANY_NAME16] +Comment= + +[ERROR_FILEGROUP] +Comment= + +[ERROR_MOVEDATA] +Comment= + +[PRODUCT_VERSION] +Comment= + +[UNINST_KEY] +Comment= + +[Language] +Lang0=0009 +CurrentLang=0 + +[TITLE_CAPTIONBAR] +Comment= + +[PRODUCT_NAME16] +Comment= + +[Data] +Entry0=ERROR_VGARESOLUTION +Entry1=TITLE_MAIN +Entry2=TITLE_CAPTIONBAR +Entry3=UNINST_KEY +Entry4=UNINST_DISPLAY_NAME +Entry5=COMPANY_NAME +Entry6=PRODUCT_NAME +Entry7=PRODUCT_VERSION +Entry8=PRODUCT_KEY +Entry10=ERROR_UNINSTSETUP +Entry9=ERROR_MOVEDATA +Entry11=COMPANY_NAME16 +Entry12=PRODUCT_NAME16 +Entry13=ERROR_COMPONENT +Entry14=ERROR_FILEGROUP +Entry15=ERROR_FILE + +[ERROR_FILE] +Comment= + +[ERROR_VGARESOLUTION] +Comment= + +[PRODUCT_KEY] +Comment= + +[UNINST_DISPLAY_NAME] +Comment= + +[General] +Type=STRINGTABLE +Version=1.00.000 + +[ERROR_UNINSTSETUP] +Comment= + +[PRODUCT_NAME] +Comment= + diff --git a/VC++Files/InstallShield/3.23.XXcom/Text Substitutions/Build.tsb b/VC++Files/InstallShield/3.23.XXcom/Text Substitutions/Build.tsb new file mode 100644 index 00000000000..0478df14bff --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/Text Substitutions/Build.tsb @@ -0,0 +1,56 @@ +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[Data] +Key0= +Key1= +Key2= +Key3= +Key4= +Key5= +Key6= +Key7= +Key8= +Key9= + +[General] +Type=TEXTSUB +Version=1.00.000 + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + diff --git a/VC++Files/InstallShield/3.23.XXcom/Text Substitutions/Setup.tsb b/VC++Files/InstallShield/3.23.XXcom/Text Substitutions/Setup.tsb new file mode 100644 index 00000000000..258173c7a48 --- /dev/null +++ b/VC++Files/InstallShield/3.23.XXcom/Text Substitutions/Setup.tsb @@ -0,0 +1,76 @@ +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[Data] +Key0= +Key1= +Key2= +Key3= +Key4= +Key10= +Key5= +Key11= +Key6= +Key12= +Key7= +Key13= +Key8= +Key9= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[General] +Type=TEXTSUB +Version=1.00.000 + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + +[] +KeyType=4 +Value= + From beef0bf08e472b609f1cf653f4607e5981e9e23a Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 18 Jun 2003 22:08:04 +0200 Subject: [PATCH 044/237] - Added /usr/lib64 to the path to search for libssl.a (required on AMD64) - fixed a typo --- acinclude.m4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 4d7900acc3d..abeb2024f4a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -711,7 +711,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ done for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \ -/usr/lib /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do +/usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do if test -f $d/libssl.a ; then OPENSSL_LIB=$d fi @@ -721,7 +721,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ echo "Could not find an installation of OpenSSL" if test -n "$OPENSSL_LIB" ; then if test "$IS_LINUX" = "true"; then - echo "Looks like you've forgotted to install OpenSSL development RPM" + echo "Looks like you've forgotten to install OpenSSL development RPM" fi fi exit 1 From eb0a4977cae00e2464c55d4f7ba3f4af76f93f90 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 19 Jun 2003 01:05:24 +0300 Subject: [PATCH 045/237] page0page.c: Track an assertion failure reported on the mailing list June 18th, 2003 --- innobase/page/page0page.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/innobase/page/page0page.c b/innobase/page/page0page.c index ef5dad60c08..e087941a970 100644 --- a/innobase/page/page0page.c +++ b/innobase/page/page0page.c @@ -446,7 +446,6 @@ page_copy_rec_list_end_no_locks( page_cur_move_to_next(&cur1); } - /* Track a memory corruption bug in Windows */ ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) == PAGE_INFIMUM); page_cur_set_before_first(new_page, &cur2); @@ -456,11 +455,23 @@ page_copy_rec_list_end_no_locks( sup = page_get_supremum_rec(page); while (sup != page_cur_get_rec(&cur1)) { - ut_a( - page_cur_rec_insert(&cur2, page_cur_get_rec(&cur1), mtr)); + if (!page_cur_rec_insert(&cur2, + page_cur_get_rec(&cur1), mtr)) { + /* Track an assertion failure reported on the mailing + list on June 18th, 2003 */ + + buf_page_print(new_page); + buf_page_print(page); + ut_print_timestamp(stderr); + + fprintf(stderr, +"InnoDB: rec offset %lu, cur1 offset %lu, cur2 offset %lu\n", + (ulint)(rec - page), + (ulint)(page_cur_get_rec(&cur1) - page), + (ulint)(page_cur_get_rec(&cur2) - new_page)); + ut_a(0); + } - ut_a(mach_read_from_2(new_page + UNIV_PAGE_SIZE - 10) - == PAGE_INFIMUM); page_cur_move_to_next(&cur1); page_cur_move_to_next(&cur2); } From a05ccddd9ad22ebb72edaaf0a0811ec35955e594 Mon Sep 17 00:00:00 2001 From: "greg@gcw.ath.cx" <> Date: Thu, 19 Jun 2003 04:02:29 -0400 Subject: [PATCH 046/237] Tagged ChangeSet 1.1385 as mysql-3.23.57 --- BitKeeper/etc/logging_ok | 1 + configure.in | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 767dcab7c8a..bbf42ffcb6d 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -5,6 +5,7 @@ bar@bar.mysql.r18.ru bar@bar.udmsearch.izhnet.ru bell@sanja.is.com.ua bk@admin.bk +greg@gcw.ath.cx guilhem@mysql.com heikki@donna.mysql.fi heikki@hundin.mysql.fi diff --git a/configure.in b/configure.in index 5b690c3af78..471e97ce9cf 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, 3.23.57) +AM_INIT_AUTOMAKE(mysql, 3.23.58) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From 289d375f506aab6b46eb605baab8be5283d00c72 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Thu, 19 Jun 2003 14:02:19 +0500 Subject: [PATCH 047/237] SCRUM Task ID 894: Backport default_week_format variable to 4.0 --- mysql-test/r/func_time.result | 5 +++++ mysql-test/t/func_time.test | 4 ++++ sql/mysqld.cc | 8 +++++++- sql/set_var.cc | 4 ++++ sql/sql_class.h | 1 + sql/sql_yacc.yy | 6 +++++- 6 files changed, 26 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 06c0be86667..58a05a2336f 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -96,6 +96,11 @@ week(19981231,2) week(19981231,3) week(20000101,2) week(20000101,3) select week(20001231,2),week(20001231,3); week(20001231,2) week(20001231,3) 1 52 +set default_week_format = 2; +select week(20001231),week(20001231,2),week(20001231,0); +week(20001231) week(20001231,2) week(20001231,0) +1 1 53 +set default_week_format = 0; select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v'); date_format('1998-12-31','%x-%v') date_format('1999-01-01','%x-%v') 1998-53 1998-53 diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 3057729ab96..a51869e7d76 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -39,6 +39,10 @@ select yearweek("2000-01-06",1) as '2000', yearweek("2001-01-06",1) as '2001', y select week(19981231,2), week(19981231,3), week(20000101,2), week(20000101,3); select week(20001231,2),week(20001231,3); +set default_week_format = 2; +select week(20001231),week(20001231,2),week(20001231,0); +set default_week_format = 0; + select date_format('1998-12-31','%x-%v'),date_format('1999-01-01','%x-%v'); select date_format('1999-12-31','%x-%v'),date_format('2000-01-01','%x-%v'); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0f3500248c0..2e6e226b18e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3179,7 +3179,8 @@ enum options { OPT_BDB_CACHE_SIZE, OPT_BDB_LOG_BUFFER_SIZE, OPT_BDB_MAX_LOCK, - OPT_ERROR_LOG_FILE + OPT_ERROR_LOG_FILE, + OPT_DEFAULT_WEEK_FORMAT }; @@ -3988,6 +3989,11 @@ replicating a LOAD DATA INFILE command", (gptr*) &global_system_variables.net_wait_timeout, (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + { "default-week-format", OPT_DEFAULT_WEEK_FORMAT, + "The default week format used by WEEK() functions.", + (gptr*) &global_system_variables.default_week_format, + (gptr*) &max_system_variables.default_week_format, + 0, GET_ULONG, REQUIRED_ARG, 0, 0, 3L, 0, 1, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/sql/set_var.cc b/sql/set_var.cc index 1da187598c4..32603ec51d9 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -296,6 +296,8 @@ static sys_var_slave_skip_counter sys_slave_skip_counter("sql_slave_skip_counter static sys_var_rand_seed1 sys_rand_seed1("rand_seed1"); static sys_var_rand_seed2 sys_rand_seed2("rand_seed2"); +static sys_var_thd_ulong sys_default_week_format("default_week_format", + &SV::default_week_format); /* List of all variables for initialisation and storage in hash @@ -316,6 +318,7 @@ sys_var *sys_variables[]= &sys_bulk_insert_buff_size, &sys_concurrent_insert, &sys_connect_timeout, + &sys_default_week_format, &sys_convert_charset, &sys_delay_key_write, &sys_delayed_insert_limit, @@ -421,6 +424,7 @@ struct show_var_st init_vars[]= { {sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS}, {sys_convert_charset.name, (char*) &sys_convert_charset, SHOW_SYS}, {"datadir", mysql_real_data_home, SHOW_CHAR}, + {"default_week_format", (char*) &sys_default_week_format, SHOW_SYS}, {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS}, {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS}, {sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 9857774fb84..a8a24451ecc 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -309,6 +309,7 @@ struct system_variables ulong tmp_table_size; ulong tx_isolation; ulong table_type; + ulong default_week_format; my_bool log_warnings; my_bool low_priority_updates; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4a41ad32dcc..0ff09a52a9e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2002,7 +2002,11 @@ simple_expr: | USER '(' ')' { $$= new Item_func_user(); current_thd->safe_to_cache_query=0; } | WEEK_SYM '(' expr ')' - { $$= new Item_func_week($3,new Item_int((char*) "0",0,1)); } + { + LEX *lex=Lex; + $$= new Item_func_week($3,new Item_int((char*) "0", + lex->thd->variables.default_week_format,1)); + } | WEEK_SYM '(' expr ',' expr ')' { $$= new Item_func_week($3,$5); } | YEAR_SYM '(' expr ')' From 79780cbd9cf079dc767c6beb759191efa1a7ef23 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Thu, 19 Jun 2003 15:38:52 +0500 Subject: [PATCH 048/237] Fix for bug #616 mysqld crash / SSL with SQLyog --- sql/sql_parse.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index bb06713ec4c..3b3da6d35b3 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -583,6 +583,11 @@ check_connections(THD *thd) if (thd->client_capabilities & CLIENT_SSL) { /* Do the SSL layering. */ + if (!ssl_acceptor_fd) + { + inc_host_errors(&thd->remote.sin_addr); + return(ER_HANDSHAKE_ERROR); + } DBUG_PRINT("info", ("IO layer change in progress...")); if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout)) { From 169fe2abe3ba1ab3bc427ea91e92b60ff223b903 Mon Sep 17 00:00:00 2001 From: "miguel@hegel.(none)" <> Date: Thu, 19 Jun 2003 12:09:32 -0400 Subject: [PATCH 049/237] Fix error msg. Bug #681 --- sql/nt_servc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index b917c91ce15..b18d3d00d88 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -462,7 +462,7 @@ BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType) { /* a remove operation */ if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS ))) - printf("The service doesn't exists!\n"); + printf("The service doesn't exist!\n"); else { SERVICE_STATUS ss; From 10c81fb52d88436aaebfc2fb8a0952b7f59ce50f Mon Sep 17 00:00:00 2001 From: "miguel@hegel.(none)" <> Date: Thu, 19 Jun 2003 12:38:14 -0400 Subject: [PATCH 050/237] Fix error msg. Bug #681 --- BitKeeper/etc/logging_ok | 1 + sql/nt_servc.cc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 092b6f3f2a5..9a826cffbfc 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -44,6 +44,7 @@ jorge@linux.jorge.mysql.com kaj@work.mysql.com lenz@kallisto.mysql.com lenz@mysql.com +miguel@hegel.(none) miguel@hegel.br miguel@hegel.local miguel@light. diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index b917c91ce15..b18d3d00d88 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -462,7 +462,7 @@ BOOL NTService::SeekStatus(LPCSTR szInternName, int OperationType) { /* a remove operation */ if (!(service = OpenService(scm,szInternName, SERVICE_ALL_ACCESS ))) - printf("The service doesn't exists!\n"); + printf("The service doesn't exist!\n"); else { SERVICE_STATUS ss; From faa2b41114dc8aeabdde1b1c57224f989c230b0b Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Thu, 19 Jun 2003 22:06:51 +0500 Subject: [PATCH 051/237] Bug #570 fixed --- sql/sql_update.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index b4e7750addf..3179c8e0f24 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -86,7 +86,8 @@ int mysql_update(THD *thd, table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); bzero((char*) &tables,sizeof(tables)); // For ORDER BY - tables.table = table; + tables.table= table; + tables.alias= table_list->alias; if (setup_tables(table_list) || setup_conds(thd,table_list,&conds) || setup_order(thd, &tables, all_fields, all_fields, order) || From def18de12c49070e7ad52fd515bd0de4d90a0da9 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 20 Jun 2003 13:54:22 +0200 Subject: [PATCH 052/237] Warn that --log-slave-updates is used without --log-bin and disabled (WL#998) --- sql/mysqld.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 0f3500248c0..318128f77e4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2322,6 +2322,12 @@ The server will not act as a slave."); opt_binlog_index_name,LOG_BIN); using_update_log=1; } + else if (opt_log_slave_updates) + { + sql_print_error("\ +Warning: you need to use --log-bin to make --log-slave-updates work. \ +Now disabling --log-slave-updates."); + } if (opt_bootstrap) { From 6f5cae43580cc792b2a42f049b79ead7e22919d7 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Fri, 20 Jun 2003 15:19:51 +0200 Subject: [PATCH 053/237] - added $(EXEEXT) to gen_lex_hash generation/execution to fix a build problem on Windows/cygwin (BUG#668) --- sql/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/Makefile.am b/sql/Makefile.am index a589f1379f9..e2494e50d96 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -114,8 +114,8 @@ sql_yacc.o: sql_yacc.cc sql_yacc.h $(CXXCOMPILE) $(LM_CFLAGS) -c $< lex_hash.h: lex.h gen_lex_hash.cc sql_yacc.h - $(MAKE) gen_lex_hash - ./gen_lex_hash > $@ + $(MAKE) gen_lex_hash$(EXEEXT) + ./gen_lex_hash$(EXEEXT) > $@ # Hack to ensure that lex_hash.h is built early sql_lex.o: lex_hash.h From e8a8b8c346b700aa246d089122e5880b2b40e5ae Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 20 Jun 2003 15:48:52 +0200 Subject: [PATCH 054/237] fix for BUG#691 (4.0 mysqlbinlog couldn't read 3.23 binlog). Safe parenthesis. --- client/mysqlbinlog.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 75b875b4f4e..9ef340197a7 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -396,8 +396,8 @@ static int check_header(IO_CACHE* file) if (buf[4] == START_EVENT) { uint event_len; - event_len = uint4korr(buf + 4); - old_format = (event_len < LOG_EVENT_HEADER_LEN + START_HEADER_LEN); + event_len = uint4korr(buf + EVENT_LEN_OFFSET); + old_format = (event_len < (LOG_EVENT_HEADER_LEN + START_HEADER_LEN)); } } my_b_seek(file, pos); From eb901ea4611b5d682376fb5f885e229d499bdcc0 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 20 Jun 2003 18:52:40 +0500 Subject: [PATCH 055/237] Proposed fix for #615 So now for the CREATE TABLE foo (id integer NOT NULL default 9) INSERT INTO foo VALUES (NULL); we get an error INSERT INTO foo VALUES (1), (NULL), (2); we get one warning and second record is set to 9 Is that what we want? --- sql/field_conv.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 42272dd616f..a32a635ac05 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -121,6 +121,7 @@ set_field_to_null(Field *field) field->reset(); if (current_thd->count_cuted_fields) { + field->set_default(); current_thd->cuted_fields++; // Increment error counter return 0; } @@ -175,6 +176,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) return 0; // field is set in handler.cc if (current_thd->count_cuted_fields) { + field->set_default(); current_thd->cuted_fields++; // Increment error counter return 0; } From 27c67fbfe7857c786e00f733c6d0158a46c61340 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Fri, 20 Jun 2003 20:04:52 +0500 Subject: [PATCH 056/237] Fix for bug #666 (Nice number, yeah?) --- sql/item_strfunc.cc | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 208be1ecd7f..9d4f7641b1d 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1539,37 +1539,46 @@ void Item_func_elt::update_used_tables() double Item_func_elt::val() { uint tmp; + null_value=1; if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count) - { - null_value=1; return 0.0; - } + + double result= args[tmp-1]->val(); + if (args[tmp-1]->is_null()) + return 0.0; + null_value=0; - return args[tmp-1]->val(); + return result; } longlong Item_func_elt::val_int() { uint tmp; + null_value=1; if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count) - { - null_value=1; return 0; - } + + int result= args[tmp-1]->val_int(); + if (args[tmp-1]->is_null()) + return 0; + null_value=0; - return args[tmp-1]->val_int(); + return result; } String *Item_func_elt::val_str(String *str) { uint tmp; + null_value=1; if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count) - { - null_value=1; return NULL; - } + + String *result= args[tmp-1]->val_str(str); + if (args[tmp-1]->is_null()) + return NULL; + null_value=0; - return args[tmp-1]->val_str(str); + return result; } From f0f92fe443bb3e41a0e14ccc0a4af0dc4876d9c8 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Sat, 21 Jun 2003 16:59:40 +0500 Subject: [PATCH 057/237] Proposed fix for #674 This crash happens in rather exotic case when we try to run SELECT DISTINCT some_func(SUM(some_field)) GROUP BY another_field; on a table with single row. Optimizer marks this table as const, sets group=NULL (with remove_const) thus, create_tmp_table makes mistake collecting columns for temporary table and then crashes because the field_count gets less than hidden_columns_count. --- sql/sql_select.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0e8b191e4ef..cb056100e2a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -453,6 +453,9 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, goto err; thd->proc_info="preparing"; + + select_distinct= select_distinct && (join.const_tables != join.tables); + if (result->initialize_tables(&join)) goto err; if (join.const_table_map != join.found_const_table_map && From dcbcb78536b1b3798074cc93c299537a2bfdb66a Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 21 Jun 2003 16:32:27 +0200 Subject: [PATCH 058/237] Can't believe it: one more cset (04-27) which never found his way to the central repository (incredible that I forgot to push, but why not). So unfortunately the bugfix missed 3.23.57 and will be in .58 :( Instead of looking like working (bug #198), replication between a 3.23 slave and 4.0 master should frankly stop. Here we detect 4.0 masters in the 3.23 slave code when we see a strange Rotate event, and in that case we print an error and stop. 4.0.13 and older masters will be "often" caught (see the patch); 4.0.14 and newer masters will always be immediately caught. --- sql/slave.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sql/slave.cc b/sql/slave.cc index 39c3d31ee66..50cb224d83d 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1216,6 +1216,28 @@ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) Rotate_log_event* rev = (Rotate_log_event*)ev; int ident_len = rev->ident_len; pthread_mutex_lock(&mi->lock); + /* + If the master is 4.0, he has an incompatible binlog format, which we + cannot read. We always can detect this in _fake_ Rotate events, where we + see zeros at the beginning of the expected binlog's filename (this is + because 4.0 _fake_ Rotate events have zeros in the 'log_pos' and 'flags' + parts of the event header). + Consider the following test as a sanity check, which must always pass, + and which has the good side effect of catching 4.0 masters. + Masters >= 4.0.14 will always send a fake Rotate event (even if the slave + asked for a position >4) so we are 100% sure to catch the problem. + */ + if (!ident_len || !(rev->new_log_ident[0])) + { + sql_print_error("Slave: could not parse Rotate event; it *might* be \ +that your master's version is 4.0 or newer, which cannot be replicated by \ +3.23 slaves (in that case you need to upgrade your slave to 4.0 or newer)"); + delete ev; + pthread_cond_broadcast(&mi->cond); + pthread_mutex_unlock(&mi->lock); + return 1; + } + memcpy(mi->log_file_name, rev->new_log_ident,ident_len ); mi->log_file_name[ident_len] = 0; mi->pos = 4; // skip magic number From b24fd86a91519c879c8c31fad9f918d3847ca797 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Sat, 21 Jun 2003 20:17:50 +0500 Subject: [PATCH 059/237] Fix for bug #628 --- sql/item_strfunc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 208be1ecd7f..1edd0e68687 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1482,7 +1482,7 @@ String *Item_func_format::val_str(String *str) str= copy_if_not_alloced(&tmp_str,str,length); str->length(length); tmp= (char*) str->ptr()+length - dec-1; - for (pos= (char*) str->ptr()+length ; pos != tmp; pos--) + for (pos= (char*) str->ptr()+length-1; pos != tmp; pos--) pos[0]= pos[-(int) diff]; while (diff) { From 04e5a6baa9e9a33539585456dce316e8e2fd1227 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 21 Jun 2003 18:10:59 +0200 Subject: [PATCH 060/237] Always send a fake Rotate event (this is roughly 70 bytes) when starting binlog_dump. This way 3.23.58 slaves will always detect a 4.0.14 master (and stop) immediately. BUG#198. --- mysql-test/r/rpl_log.result | 2 +- mysql-test/r/rpl_log_pos.result | 2 +- sql/sql_repl.cc | 43 ++++++++++++++++++++++----------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 425c376af1e..316bf1f3dd0 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -93,6 +93,6 @@ slave-bin.002 62 Query 1 168 use test; insert into t1 values (1) slave-bin.002 122 Query 1 228 use test; drop table t1 show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1522 master-bin.002 Yes Yes 0 0 276 1526 +127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1563 master-bin.002 Yes Yes 0 0 276 1567 show binlog events in 'slave-bin.005' from 4; Error when executing command SHOW BINLOG EVENTS: Could not find target log diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result index e76b565813f..3224e84fa31 100644 --- a/mysql-test/r/rpl_log_pos.result +++ b/mysql-test/r/rpl_log_pos.result @@ -21,7 +21,7 @@ Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Lo slave start; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 4 master-bin.001 No Yes 0 0 73 4 +127.0.0.1 root MASTER_PORT 1 master-bin.001 73 slave-relay-bin.001 45 master-bin.001 No Yes 0 0 73 45 slave stop; change master to master_log_pos=173; slave start; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index e3af076da1f..a3cfe442b0f 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -51,7 +51,7 @@ int check_binlog_magic(IO_CACHE* log, const char** errmsg) } static int fake_rotate_event(NET* net, String* packet, char* log_file_name, - const char**errmsg) + ulonglong position, const char**errmsg) { char header[LOG_EVENT_HEADER_LEN], buf[ROTATE_HEADER_LEN]; memset(header, 0, 4); // when does not matter @@ -69,7 +69,7 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name, packet->append(header, sizeof(header)); /* We need to split the next statement because of problem with cxx */ - int4store(buf,4); // tell slave to skip magic number + int4store(buf,position); int4store(buf+4,0); packet->append(buf, ROTATE_HEADER_LEN); packet->append(p,ident_len); @@ -382,17 +382,30 @@ impossible position"; */ packet->set("\0", 1); - // if we are at the start of the log - if (pos == BIN_LOG_HEADER_SIZE) + /* + Before 4.0.14 we called fake_rotate_event below only if + (pos == BIN_LOG_HEADER_SIZE), because if this is false then the slave + already knows the binlog's name. + Now we always call fake_rotate_event; if the slave already knew the log's + name (ex: CHANGE MASTER TO MASTER_LOG_FILE=...) this is useless but does not + harm much. It is nice for 3.23 (>=.58) slaves which test Rotate events + to see if the master is 4.0 (then they choose to stop because they can't + replicate 4.0); by always calling fake_rotate_event we are sure that 3.23.58 + and newer will detect the problem as soon as replication starts (BUG#198). + Always calling fake_rotate_event makes sending of normal + (=from-binlog) Rotate events a priori unneeded, but it is not so simple: the + 2 Rotate events are not equivalent, the normal one is before the Stop event, + the fake one is after. If we don't send the normal one, then the Stop event + will be interpreted (by existing 4.0 slaves) as "the master stopped", which + is wrong. So for safety, given that we want minimum modification of 4.0, we + send the normal and fake Rotates. + */ + if (fake_rotate_event(net, packet, log_file_name, pos, &errmsg)) { - // tell the client log name with a fake rotate_event - if (fake_rotate_event(net, packet, log_file_name, &errmsg)) - { - my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; - goto err; - } - packet->set("\0", 1); + my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; + goto err; } + packet->set("\0", 1); while (!net->error && net->vio != 0 && !thd->killed) { @@ -585,10 +598,12 @@ Increase max_allowed_packet on master"; end_io_cache(&log); (void) my_close(file, MYF(MY_WME)); - // fake Rotate_log event just in case it did not make it to the log - // otherwise the slave make get confused about the offset + /* + Even if the previous log contained a Rotate_log_event, we still fake + one. + */ if ((file=open_binlog(&log, log_file_name, &errmsg)) < 0 || - fake_rotate_event(net, packet, log_file_name, &errmsg)) + fake_rotate_event(net, packet, log_file_name, BIN_LOG_HEADER_SIZE, &errmsg)) { my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; goto err; From 9990ce576b666980904ae8202b079bdd8fdd00ba Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sun, 22 Jun 2003 14:10:46 +0200 Subject: [PATCH 061/237] Fixed cleanup_load_tmpdir() which deleted nothing. --- sql/log_event.cc | 9 ++++++--- sql/sql_repl.cc | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index ff968babcf0..727b2052969 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -168,12 +168,15 @@ static void cleanup_load_tmpdir() uint i; if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME)))) return; - + char fname[FN_REFLEN]; for (i=0 ; i < (uint)dirp->number_off_files; i++) { file=dirp->dir_entry+i; if (is_prefix(file->name,"SQL_LOAD-")) - my_delete(file->name, MYF(0)); + { + fn_format(fname,file->name,slave_load_tmpdir,"",0); + my_delete(fname, MYF(0)); + } } my_dirend(dirp); @@ -813,7 +816,7 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len, int Rotate_log_event::write_data(IO_CACHE* file) { char buf[ROTATE_HEADER_LEN]; - int8store(buf, pos + R_POS_OFFSET); + int8store(buf + R_POS_OFFSET, pos); return (my_b_safe_write(file, (byte*)buf, ROTATE_HEADER_LEN) || my_b_safe_write(file, (byte*)new_log_ident, (uint) ident_len)); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index a3cfe442b0f..d0ed1a19d96 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -68,9 +68,12 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name, int4store(header + LOG_POS_OFFSET, 0); packet->append(header, sizeof(header)); - /* We need to split the next statement because of problem with cxx */ - int4store(buf,position); - int4store(buf+4,0); + /* + An old comment said talked about a need for splitting the int8store below + into 2 int4store because of a problem with cxx; I can't understand that as + we already use int8store in Rotatel_log_event::write_data(). + */ + int8store(buf+R_POS_OFFSET,position); packet->append(buf, ROTATE_HEADER_LEN); packet->append(p,ident_len); if (my_net_write(net, (char*)packet->ptr(), packet->length())) From e2efb08c505d6e5edafb06bfebf3b089815dbf27 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sun, 22 Jun 2003 16:20:06 +0300 Subject: [PATCH 062/237] dict0dict.h, dict0dict.c, ha_innodb.cc: In ORDER BY MySQL seems to set the key read flag also in the case where the primary key contains only a prefix of a column - not the whole column; to prevent potential bugs retrieve the whole column if the index contains a prefix of it --- innobase/dict/dict0dict.c | 40 ++++++++++++++++++++++++++++++++++++ innobase/include/dict0dict.h | 10 +++++++++ sql/ha_innodb.cc | 11 ++++++---- 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index 2fc05b1923f..b1d7b5f762e 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -494,6 +494,46 @@ dict_index_get_nth_col_pos( return(ULINT_UNDEFINED); } +/************************************************************************ +Returns TRUE if the index contains a column or a prefix of that column. */ + +ibool +dict_index_contains_col_or_prefix( +/*==============================*/ + /* out: TRUE if contains the column or its + prefix */ + dict_index_t* index, /* in: index */ + ulint n) /* in: column number */ +{ + dict_field_t* field; + dict_col_t* col; + ulint pos; + ulint n_fields; + + ut_ad(index); + ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); + + if (index->type & DICT_CLUSTERED) { + + return(TRUE); + } + + col = dict_table_get_nth_col(index->table, n); + + n_fields = dict_index_get_n_fields(index); + + for (pos = 0; pos < n_fields; pos++) { + field = dict_index_get_nth_field(index, pos); + + if (col == field->col) { + + return(TRUE); + } + } + + return(FALSE); +} + /************************************************************************ Looks for a matching field in an index. The column and the prefix len have to be the same. */ diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h index e88c6a52bcb..b5ec5381db2 100644 --- a/innobase/include/dict0dict.h +++ b/innobase/include/dict0dict.h @@ -569,6 +569,16 @@ dict_index_get_nth_col_pos( dict_index_t* index, /* in: index */ ulint n); /* in: column number */ /************************************************************************ +Returns TRUE if the index contains a column or a prefix of that column. */ + +ibool +dict_index_contains_col_or_prefix( +/*==============================*/ + /* out: TRUE if contains the column or its + prefix */ + dict_index_t* index, /* in: index */ + ulint n); /* in: column number */ +/************************************************************************ Looks for a matching field in an index. The column and the prefix len has to be the same. */ diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 795cffc0776..a6528209b3e 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1863,7 +1863,11 @@ build_template( if (prebuilt->read_just_key) { /* MySQL has instructed us that it is enough to - fetch the columns in the key */ + fetch the columns in the key; looks like MySQL + can set this flag also when there is only a + prefix of the column in the key: in that case we + retrieve the whole column from the clustered + index */ fetch_all_in_key = TRUE; } else { @@ -1924,9 +1928,8 @@ build_template( field = table->field[i]; if (templ_type == ROW_MYSQL_REC_FIELDS - && !(fetch_all_in_key && - ULINT_UNDEFINED != dict_index_get_nth_col_pos( - index, i)) + && !(fetch_all_in_key + && dict_index_contains_col_or_prefix(index, i)) && thd->query_id != field->query_id && thd->query_id != (field->query_id ^ MAX_ULONG_BIT) && thd->query_id != From 9791f47eee7177cd67019daa355284e7457a0afb Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Mon, 23 Jun 2003 13:03:04 +0300 Subject: [PATCH 063/237] Added analyze as alias for optimize --- sql/ha_innodb.cc | 6 ++++++ sql/ha_innodb.h | 1 + 2 files changed, 7 insertions(+) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index fd030fff091..72267f2426c 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3847,6 +3847,12 @@ ha_innobase::analyze( return(0); } + +int ha_innobase::optimize(THD* thd, HA_CHECK_OPT* check_opt) +{ + return ha_innobase::analyze(thd,check_opt); +} + /*********************************************************************** Tries to check that an InnoDB table is not corrupted. If corruption is noticed, prints to stderr information about it. In case of corruption diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 1a9b1b16c64..3f354a2fa11 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -153,6 +153,7 @@ class ha_innobase: public handler void position(const byte *record); void info(uint); int analyze(THD* thd,HA_CHECK_OPT* check_opt); + int optimize(THD* thd,HA_CHECK_OPT* check_opt); int extra(enum ha_extra_function operation); int reset(void); int external_lock(THD *thd, int lock_type); From c6d9d57b37581cebdeacef29e8823947d40cc757 Mon Sep 17 00:00:00 2001 From: "serg@sergbook.mylan" <> Date: Mon, 23 Jun 2003 12:48:55 +0200 Subject: [PATCH 064/237] fixed bug in references column grants --- BitKeeper/etc/logging_ok | 1 + sql/sql_acl.h | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 092b6f3f2a5..9975c883180 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -84,6 +84,7 @@ sasha@mysql.sashanet.com serg@build.mysql2.com serg@serg.mylan serg@serg.mysql.com +serg@sergbook.mylan serg@sergbook.mysql.com sinisa@rhols221.adsl.netsonic.fi tfr@beta.frontier86.ee diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 1d074fe6001..f3fdf950a12 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -76,8 +76,8 @@ #define get_rights_for_db(A) (((A) & 63) | (((A) & DB_CHUNK1) >> 4) | (((A) & DB_CHUNK2) >> 6)) #define fix_rights_for_table(A) (((A) & 63) | (((A) & ~63) << 4)) #define get_rights_for_table(A) (((A) & 63) | (((A) & ~63) >> 4)) -#define fix_rights_for_column(A) (((A) & COL_ACLS) | ((A & ~COL_ACLS) << 7)) -#define get_rights_for_column(A) (((A) & COL_ACLS) | ((A & ~COL_ACLS) >> 7)) +#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 7)) +#define get_rights_for_column(A) (((A) & 7) | (((A) & ~7) >> 7)) /* prototypes */ From 438ed49691e92f0f4a0b9895c2fa59b1b2b2698d Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Mon, 23 Jun 2003 16:05:22 +0300 Subject: [PATCH 065/237] Removing one fix. --- sql/sql_acl.cc | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index e2946022ddf..12ea3a94464 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2038,7 +2038,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, check->column.c_ptr(), table_list->alias); DBUG_RETURN(-1); } - column_priv |= check->rights & COL_ACLS; + column_priv |= check->rights | (rights & COL_ACLS); } close_thread_tables(thd); } @@ -2173,12 +2173,7 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } else { - /* - This code makes sure that if there is X privilege on the entire table and - X can be also a column privilege, that granting column privilege does not - revoke a table privilege. - */ - column_priv&= ~(grant_table->privs & ~grant_table->cols); + column_priv|= grant_table->cols; } @@ -2191,13 +2186,13 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, { // Crashend table ?? result= -1; /* purecov: deadcode */ } - else if (tables[2].table && (column_priv | revoke_grant)) + else if (tables[2].table) { if ((replace_column_table(grant_table,tables[2].table, *Str, columns, table_list->db, table_list->real_name, - (revoke_grant) ? rights : column_priv, revoke_grant))) + rights, revoke_grant))) { result= -1; } From a51ea1114702efac99abd349e9dd2e0827af70b4 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Mon, 23 Jun 2003 20:03:59 +0300 Subject: [PATCH 066/237] SHOW GRANTS hided real grants when grants on both column and table (Bug 654) --- mysql-test/r/grant.result | 47 ++++- mysql-test/t/grant.test | 34 +++- sql/sql_acl.cc | 361 +++++++++++++++++++++----------------- sql/sql_acl.h | 4 +- 4 files changed, 279 insertions(+), 167 deletions(-) diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index c1dcd5c29e9..76080c85511 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1,3 +1,4 @@ +drop table if exists t1; delete from mysql.user where user='mysqltest_1'; delete from mysql.db where user='mysqltest_1'; flush privileges; @@ -64,8 +65,44 @@ GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TE revoke all privileges on mysqltest.* from mysqltest_1@localhost; delete from mysql.user where user='mysqltest_1'; flush privileges; -grant usage on test.* to user@localhost with grant option; -show grants for user@localhost; -Grants for user@localhost -GRANT USAGE ON *.* TO 'user'@'localhost' -GRANT USAGE ON `test`.* TO 'user'@'localhost' WITH GRANT OPTION +grant usage on test.* to mysqltest_1@localhost with grant option; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT USAGE ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION +GRANT USAGE ON `test`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1'; +delete from mysql.columns_priv where user='mysqltest_1'; +flush privileges; +create table t1 (a int); +GRANT select,update,insert on t1 to mysqltest_1@localhost; +GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT, SELECT (a), INSERT, INSERT (a), UPDATE, UPDATE (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost' +select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; +table_priv column_priv +Select,Insert,Update Select,Insert,Update,References +REVOKE select (a), update on t1 from mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT, INSERT, INSERT (a), REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost' +REVOKE insert,insert (a) on t1 from mysqltest_1@localhost; +GRANT references on t1 to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +Grants for mysqltest_1@localhost +GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' +GRANT SELECT, REFERENCES, REFERENCES (a) ON `test`.`t1` TO 'mysqltest_1'@'localhost' +select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; +table_priv column_priv +Select,References References +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1'; +delete from mysql.columns_priv where user='mysqltest_1'; +flush privileges; +drop table t1; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index bd04b2e4c41..b18ae941c26 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1,3 +1,7 @@ +--disable_warnings +drop table if exists t1; +--enable_warnings + # # Test that SSL options works properly # @@ -39,6 +43,32 @@ show grants for mysqltest_1@localhost; revoke all privileges on mysqltest.* from mysqltest_1@localhost; delete from mysql.user where user='mysqltest_1'; flush privileges; -grant usage on test.* to user@localhost with grant option; -show grants for user@localhost; +grant usage on test.* to mysqltest_1@localhost with grant option; +show grants for mysqltest_1@localhost; +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1'; +delete from mysql.columns_priv where user='mysqltest_1'; +flush privileges; +# +# Test what happens when you have same table and colum level grants +# + +create table t1 (a int); +GRANT select,update,insert on t1 to mysqltest_1@localhost; +GRANT select (a), update (a),insert(a), references(a) on t1 to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; +REVOKE select (a), update on t1 from mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +REVOKE insert,insert (a) on t1 from mysqltest_1@localhost; +GRANT references on t1 to mysqltest_1@localhost; +show grants for mysqltest_1@localhost; +select table_priv,column_priv from mysql.tables_priv where user="mysqltest_1"; +delete from mysql.user where user='mysqltest_1'; +delete from mysql.db where user='mysqltest_1'; +delete from mysql.tables_priv where user='mysqltest_1'; +delete from mysql.columns_priv where user='mysqltest_1'; +flush privileges; +drop table t1; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f01248bb682..c93e082e0ff 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -193,7 +193,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) host.db= get_field(&mem, table,1); host.access= get_access(table,2); host.access= fix_rights_for_db(host.access); - host.sort= get_sort(2,host.host.hostname,host.db); + host.sort= get_sort(2,host.host.hostname,host.db); #ifndef TO_BE_REMOVED if (table->fields == 8) { // Without grant @@ -213,8 +213,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) if (table->field[2]->field_length == 8 && protocol_version == PROTOCOL_VERSION) { - sql_print_error( - "Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */ + sql_print_error("Old 'user' table. (Check README or the Reference manual). Continuing --old-protocol"); /* purecov: tested */ protocol_version=9; /* purecov: tested */ } @@ -247,7 +246,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) user.sort=get_sort(2,user.host.hostname,user.user); user.hostname_length= (user.host.hostname ? (uint) strlen(user.host.hostname) : 0); - if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */ + if (table->fields >= 31) /* Starting from 4.0.2 we have more fields */ { char *ssl_type=get_field(&mem, table, 24); if (!ssl_type) @@ -259,7 +258,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) else /* !strcmp(ssl_type, "SPECIFIED") */ user.ssl_type=SSL_TYPE_SPECIFIED; - user.ssl_cipher= get_field(&mem, table, 25); + user.ssl_cipher= get_field(&mem, table, 25); user.x509_issuer= get_field(&mem, table, 26); user.x509_subject= get_field(&mem, table, 27); @@ -368,7 +367,14 @@ void acl_free(bool end) } } - /* Reload acl list if possible */ + +/* + Forget current privileges and read new privileges from the privilege tables + + SYNOPSIS + acl_reload() + thd Thread handle +*/ void acl_reload(THD *thd) { @@ -493,8 +499,8 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *message, - char **priv_user, char *priv_host, - bool old_ver, USER_RESOURCES *mqh) + char **priv_user, char *priv_host, + bool old_ver, USER_RESOURCES *mqh) { ulong user_access=NO_ACCESS; *priv_user=(char*) user; @@ -526,15 +532,15 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, { #ifdef HAVE_OPENSSL Vio *vio=thd->net.vio; - /* + /* In this point we know that user is allowed to connect from given host by given username/password pair. Now we check if SSL is required, if user is using SSL and if X509 certificate attributes are OK */ - switch (acl_user->ssl_type) { + switch (acl_user->ssl_type) { case SSL_TYPE_NOT_SPECIFIED: // Impossible - case SSL_TYPE_NONE: /* SSL is not required to connect */ + case SSL_TYPE_NONE: /* SSL is not required to connect */ user_access=acl_user->access; break; case SSL_TYPE_ANY: /* Any kind of SSL is good enough */ @@ -544,7 +550,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, case SSL_TYPE_X509: /* Client should have any valid certificate. */ /* We need to check for absence of SSL because without SSL - we should reject connection. + we should reject connection. */ if (vio_type(vio) == VIO_TYPE_SSL && SSL_get_peer_certificate(vio->ssl_)) user_access=acl_user->access; @@ -653,12 +659,12 @@ static byte* check_get_key(ACL_USER *buff,uint *length, } static void acl_update_user(const char *user, const char *host, - const char *password, + const char *password, enum SSL_type ssl_type, const char *ssl_cipher, const char *x509_issuer, const char *x509_subject, - USER_RESOURCES *mqh, + USER_RESOURCES *mqh, ulong privileges) { for (uint i=0 ; i < acl_users.elements ; i++) @@ -707,7 +713,7 @@ static void acl_update_user(const char *user, const char *host, static void acl_insert_user(const char *user, const char *host, - const char *password, + const char *password, enum SSL_type ssl_type, const char *ssl_cipher, const char *x509_issuer, @@ -805,9 +811,10 @@ static void acl_insert_db(const char *user, const char *host, const char *db, } -/***************************************************************************** -** Get privilege for a host, user and db combination -*****************************************************************************/ + +/* + Get privilege for a host, user and db combination +*/ ulong acl_get(const char *host, const char *ip, const char *bin_ip, const char *user, const char *db) @@ -929,11 +936,14 @@ int wild_case_compare(const char *str,const char *wildstr) DBUG_RETURN (*str != '\0'); } -/***************************************************************************** -** check if there are any possible matching entries for this host -** All host names without wild cards are stored in a hash table, -** entries with wildcards are stored in a dynamic array -*****************************************************************************/ + +/* + Check if there are any possible matching entries for this host + + NOTES + All host names without wild cards are stored in a hash table, + entries with wildcards are stored in a dynamic array +*/ static void init_check_host(void) { @@ -1006,10 +1016,6 @@ bool acl_check_host(const char *host, const char *ip) return 1; // Host is not allowed } -/***************************************************************************** - Change password for the user if it's not an anonymous user - Note: This should write the error directly to the client! -*****************************************************************************/ /* Check if the user is allowed to change password @@ -1021,8 +1027,8 @@ bool acl_check_host(const char *host, const char *ip) user user name RETURN VALUE - 0 OK - 1 ERROR ; In this case the error is sent to the client. + 0 OK + 1 ERROR ; In this case the error is sent to the client. */ bool check_change_password(THD *thd, const char *host, const char *user) @@ -1061,7 +1067,7 @@ bool check_change_password(THD *thd, const char *host, const char *user) RETURN VALUES 0 ok 1 ERROR; In this case the error is sent to the client. -*/ +*/ bool change_password(THD *thd, const char *host, const char *user, char *new_password) @@ -1127,7 +1133,7 @@ find_acl_user(const char *host, const char *user) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),", - user,acl_user->user,(host),(acl_user->host))); + user,acl_user->user,(host),(acl_user->host))); if (!acl_user->user && !user[0] || acl_user->user && !strcmp(user,acl_user->user)) { @@ -1140,15 +1146,18 @@ find_acl_user(const char *host, const char *user) DBUG_RETURN(0); } -/***************************************************************************** - Handle comparing of hostname - A hostname may be of type: - hostname (May include wildcards); monty.pp.sci.fi - ip (May include wildcards); 192.168.0.0 - ip/netmask 192.168.0.0/255.255.255.0 - A net mask of 0.0.0.0 is not allowed. -*****************************************************************************/ +/* + Comparing of hostnames + + NOTES + A hostname may be of type: + hostname (May include wildcards); monty.pp.sci.fi + ip (May include wildcards); 192.168.0.0 + ip/netmask 192.168.0.0/255.255.255.0 + + A net mask of 0.0.0.0 is not allowed. +*/ static const char *calc_ip(const char *ip, long *val, char end) { @@ -1195,9 +1204,9 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, } -/**************************************************************************** - Code to update grants in the user and database privilege tables -****************************************************************************/ +/* + Update grants in the user and database privilege tables +*/ static bool update_user_table(THD *thd, const char *host, const char *user, const char *new_password) @@ -1263,7 +1272,7 @@ static bool test_if_create_new_users(THD *thd) /**************************************************************************** -** Handle GRANT commands + Handle GRANT commands ****************************************************************************/ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, @@ -1285,8 +1294,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (combo.password.length != HASH_PASSWORD_LENGTH) { my_printf_error(ER_PASSWORD_NO_MATCH, - "Password hash should be a %d-digit hexadecimal number", - MYF(0),HASH_PASSWORD_LENGTH); + "Password hash should be a %d-digit hexadecimal number", + MYF(0),HASH_PASSWORD_LENGTH); DBUG_RETURN(-1); } password=combo.password.str; @@ -1459,7 +1468,7 @@ static int replace_db_table(TABLE *table, const char *db, char what= (revoke_grant) ? 'N' : 'Y'; DBUG_ENTER("replace_db_table"); - // is there such a user in user table in memory ???? + /* Check if there is such a user in user table in memory? */ if (!initialized || !find_acl_user(combo.host.str,combo.user.str)) { my_error(ER_PASSWORD_NO_MATCH,MYF(0)); @@ -1471,7 +1480,7 @@ static int replace_db_table(TABLE *table, const char *db, table->field[2]->store(combo.user.str,combo.user.length); table->file->index_init(0); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr,0, - HA_READ_KEY_EXACT)) + HA_READ_KEY_EXACT)) { if (what == 'N') { // no row, no revoke @@ -1502,7 +1511,7 @@ static int replace_db_table(TABLE *table, const char *db, if (old_row_exists) { - // update old existing row + /* update old existing row */ if (rights) { if ((error=table->file->update_row(table->record[1],table->record[0]))) @@ -1529,11 +1538,11 @@ static int replace_db_table(TABLE *table, const char *db, DBUG_RETURN(0); /* This could only happen if the grant tables got corrupted */ - table_error: +table_error: table->file->print_error(error,MYF(0)); /* purecov: deadcode */ table->file->index_end(); - abort: +abort: DBUG_RETURN(-1); } @@ -1649,7 +1658,7 @@ public: if (!(mem_check = new GRANT_COLUMN(*res, fix_rights_for_column(priv)))) { - // Don't use this entry + /* Don't use this entry */ privs = cols = 0; /* purecov: deadcode */ return; /* purecov: deadcode */ } @@ -1827,7 +1836,7 @@ static int replace_column_table(GRANT_TABLE *g_t, key_length, HA_READ_KEY_EXACT)) goto end; - // Scan trough all rows with the same host,db,user and table + /* Scan through all rows with the same host,db,user and table */ do { ulong privileges = (ulong) table->field[6]->val_int(); @@ -1877,7 +1886,7 @@ static int replace_column_table(GRANT_TABLE *g_t, !key_cmp(table,key,0,key_length)); } - end: +end: table->file->index_end(); DBUG_RETURN(result); } @@ -1947,7 +1956,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, if (revoke_grant) { - // column rights are already fixed in mysql_table_grant ! + /* column rights are already fixed in mysql_table_grant */ store_table_rights=j & ~store_table_rights; } else @@ -1983,7 +1992,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, if (rights | col_rights) { grant_table->privs= rights; - grant_table->cols= col_rights; + grant_table->cols= col_rights; } else { @@ -1991,19 +2000,36 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } DBUG_RETURN(0); - /* This should never happen */ - table_error: + /* This should never happen */ +table_error: table->file->print_error(error,MYF(0)); /* purecov: deadcode */ DBUG_RETURN(-1); /* purecov: deadcode */ } +/* + Store table level and column level grants in the privilege tables + + SYNOPSIS + mysql_table_grant() + thd Thread handle + table_list List of tables to give grant + user_list List of users to give grant + columns List of columns to give grant + rights Table level grant + revoke_grant Set to 1 if this is a REVOKE command + + RETURN + 0 ok + 1 error +*/ + int mysql_table_grant(THD *thd, TABLE_LIST *table_list, List &user_list, List &columns, ulong rights, bool revoke_grant) { - ulong column_priv = 0; + ulong column_priv= 0; List_iterator str_list (user_list); LEX_USER *Str; TABLE_LIST tables[3]; @@ -2024,21 +2050,21 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (columns.elements && !revoke_grant) { TABLE *table; - class LEX_COLUMN *check; - List_iterator iter(columns); + class LEX_COLUMN *column; + List_iterator column_iter(columns); if (!(table=open_ltable(thd,table_list,TL_READ))) DBUG_RETURN(-1); - while ((check = iter++)) + while ((column = column_iter++)) { - if (!find_field_in_table(thd,table,check->column.ptr(), - check->column.length(),0,0)) + if (!find_field_in_table(thd,table,column->column.ptr(), + column->column.length(),0,0)) { my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR),MYF(0), - check->column.c_ptr(), table_list->alias); + column->column.c_ptr(), table_list->alias); DBUG_RETURN(-1); } - column_priv |= check->rights | (rights & COL_ACLS); + column_priv|= column->rights; } close_thread_tables(thd); } @@ -2148,21 +2174,21 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, /* If revoke_grant, calculate the new column privilege for tables_priv */ if (revoke_grant) { - class LEX_COLUMN *check; - List_iterator iter(columns); + class LEX_COLUMN *column; + List_iterator column_iter(columns); GRANT_COLUMN *grant_column; /* Fix old grants */ - while ((check = iter++)) + while ((column = column_iter++)) { grant_column = column_hash_search(grant_table, - check->column.ptr(), - check->column.length()); + column->column.ptr(), + column->column.length()); if (grant_column) - grant_column->rights&= ~(check->rights | rights); + grant_column->rights&= ~(column->rights | rights); } /* scan trough all columns to get new column grant */ - column_priv=0; + column_priv= 0; for (uint idx=0 ; idx < grant_table->hash_columns.records ; idx++) { grant_column= (GRANT_COLUMN*) hash_element(&grant_table->hash_columns, @@ -2259,7 +2285,7 @@ int mysql_grant (THD *thd, const char *db, List &list, if (!revoke_grant) create_new_users= test_if_create_new_users(thd); - // go through users in user_list + /* go through users in user_list */ pthread_mutex_lock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); grant_version++; @@ -2280,7 +2306,7 @@ int mysql_grant (THD *thd, const char *db, List &list, continue; } if ((replace_user_table(thd, - tables[0].table, + tables[0].table, *Str, (!db ? rights : 0), revoke_grant, create_new_users))) @@ -2401,7 +2427,16 @@ end: } -/* Reload grant array if possible */ +/* + Reload grant array if possible + + SYNOPSIS + grant_reload() + thd Thread handler + + NOTES + Locked tables are checked by acl_init and doesn't have to be checked here +*/ void grant_reload(THD *thd) { @@ -2410,8 +2445,6 @@ void grant_reload(THD *thd) MEM_ROOT old_mem; DBUG_ENTER("grant_reload"); - // Locked tables are checked by acl_init and doesn't have to be checked here - pthread_mutex_lock(&LOCK_grant); grant_version++; old_hash_tables=hash_tables; @@ -2487,13 +2520,13 @@ bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, pthread_mutex_unlock(&LOCK_grant); return 0; - err: +err: pthread_mutex_unlock(&LOCK_grant); if (!no_errors) // Not a silent skip of table { const char *command=""; if (want_access & SELECT_ACL) - command ="select"; + command ="select"; else if (want_access & INSERT_ACL) command = "insert"; else if (want_access & UPDATE_ACL) @@ -2534,7 +2567,7 @@ bool check_grant_column(THD *thd,TABLE *table, const char *name, pthread_mutex_lock(&LOCK_grant); - // reload table if someone has modified any grants + /* reload table if someone has modified any grants */ if (table->grant.version != grant_version) { @@ -2594,7 +2627,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table) pthread_mutex_lock(&LOCK_grant); - // reload table if someone has modified any grants + /* reload table if someone has modified any grants */ if (table->grant.version != grant_version) { @@ -2604,7 +2637,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table) table->real_name,0); /* purecov: inspected */ table->grant.version=grant_version; /* purecov: inspected */ } - // The following should always be true + /* The following should always be true */ if (!(grant_table=table->grant.grant_table)) goto err; /* purecov: inspected */ @@ -2619,7 +2652,7 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table) return 0; /* We must use my_printf_error() here! */ - err: +err: pthread_mutex_unlock(&LOCK_grant); const char *command=""; @@ -2639,11 +2672,11 @@ bool check_grant_all_columns(THD *thd, ulong want_access, TABLE *table) } -/**************************************************************************** +/* Check if a user has the right to access a database Access is accepted if he has a grant for any table in the database Return 1 if access is denied -****************************************************************************/ +*/ bool check_grant_db(THD *thd,const char *db) { @@ -2683,7 +2716,7 @@ ulong get_table_grant(THD *thd, TABLE_LIST *table) pthread_mutex_lock(&LOCK_grant); grant_table = table_hash_search(thd->host,thd->ip,db,user, - table->real_name,0); + table->real_name, 0); table->grant.grant_table=grant_table; // Remember for column test table->grant.version=grant_version; if (grant_table) @@ -2701,7 +2734,7 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field) ulong priv; pthread_mutex_lock(&LOCK_grant); - // reload table if someone has modified any grants + /* reload table if someone has modified any grants */ if (table->grant.version != grant_version) { table->grant.grant_table= @@ -2726,11 +2759,20 @@ ulong get_column_grant(THD *thd, TABLE_LIST *table, Field *field) return priv; } +/* Help function for mysql_show_grants */ -/***************************************************************************** - SHOW GRANTS : send to client grant-like strings depicting user@host - privileges -*****************************************************************************/ +static void add_user_option(String *grant, ulong value, const char *name) +{ + if (value) + { + char buff[22], *p; // just as in int2str + grant->append(' '); + grant->append(name, strlen(name)); + grant->append(' '); + p=int10_to_str(value, buff, 10); + grant->append(buff,p-buff); + } +} static const char *command_array[]= { @@ -2739,13 +2781,21 @@ static const char *command_array[]= "SUPER", "CREATE TEMPORARY TABLES", "LOCK TABLES", "EXECUTE", "REPLICATION SLAVE", "REPLICATION CLIENT", }; + static uint command_lengths[]= { 6,6,6,6,6,4,6,8,7,4,5,10,5,5,14,5,23,11,7,17,18 }; -int mysql_show_grants(THD *thd,LEX_USER *lex_user) +/* + SHOW GRANTS; Send grants for a user to the client + + IMPLEMENTATION + Send to client grant-like strings depicting user@host privileges +*/ + +int mysql_show_grants(THD *thd,LEX_USER *lex_user) { ulong want_access; uint counter,index; @@ -2784,7 +2834,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) !my_strcasecmp(lex_user->host.str,host)) break; } - if (counter == acl_users.elements) + if (counter == acl_users.elements) { my_printf_error(ER_NONEXISTING_GRANT,ER(ER_NONEXISTING_GRANT), MYF(0),lex_user->user.str,lex_user->host.str); @@ -2815,13 +2865,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append("ALL PRIVILEGES",14); else if (!(want_access & ~GRANT_ACL)) global.append("USAGE",5); - else + else { bool found=0; ulong j,test_access= want_access & ~GRANT_ACL; for (counter=0, j = SELECT_ACL;j <= GLOBAL_ACLS;counter++,j <<= 1) { - if (test_access & j) + if (test_access & j) { if (found) global.append(", ",2); @@ -2831,7 +2881,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } } global.append (" ON *.* TO '",12); - global.append(lex_user->user.str,lex_user->user.length); + global.append(lex_user->user.str,lex_user->user.length); global.append ("'@'",3); global.append(lex_user->host.str,lex_user->host.length); global.append ('\''); @@ -2854,25 +2904,25 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append(" REQUIRE ",9); if (acl_user->x509_issuer) { - ssl_options++; - global.append("ISSUER \'",8); - global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); + ssl_options++; + global.append("ISSUER \'",8); + global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); global.append('\''); } if (acl_user->x509_subject) { - if (ssl_options++) - global.append(' '); - global.append("SUBJECT \'",9); - global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); + if (ssl_options++) + global.append(' '); + global.append("SUBJECT \'",9); + global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); global.append('\''); } if (acl_user->ssl_cipher) { - if (ssl_options++) - global.append(' '); - global.append("CIPHER '",8); - global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher)); + if (ssl_options++) + global.append(' '); + global.append("CIPHER '",8); + global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher)); global.append('\''); } } @@ -2880,30 +2930,15 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) (acl_user->user_resource.questions | acl_user->user_resource.updates | acl_user->user_resource.connections)) { - global.append(" WITH",5); + global.append(" WITH",5); if (want_access & GRANT_ACL) - global.append(" GRANT OPTION",13); - if (acl_user->user_resource.questions) - { - char buff[22], *p; // just as in int2str - global.append(" MAX_QUERIES_PER_HOUR ",22); - p=int10_to_str(acl_user->user_resource.questions,buff,10); - global.append(buff,p-buff); - } - if (acl_user->user_resource.updates) - { - char buff[22], *p; // just as in int2str - global.append(" MAX_UPDATES_PER_HOUR ",22); - p=int10_to_str(acl_user->user_resource.updates,buff,10); - global.append(buff,p-buff); - } - if (acl_user->user_resource.connections) - { - char buff[22], *p; // just as in int2str - global.append(" MAX_CONNECTIONS_PER_HOUR ",26); - p=int10_to_str(acl_user->user_resource.connections,buff,10); - global.append(buff,p-buff); - } + global.append(" GRANT OPTION",13); + add_user_option(&global, acl_user->user_resource.questions, + "MAX_QUERIES_PER_HOUR"); + add_user_option(&global, acl_user->user_resource.updates, + "MAX_UPDATES_PER_HOUR"); + add_user_option(&global, acl_user->user_resource.connections, + "MAX_CONNECTIONS_PER_HOUR"); } thd->packet.length(0); net_store_data(&thd->packet,global.ptr(),global.length()); @@ -2929,7 +2964,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) !my_strcasecmp(lex_user->host.str,host)) { want_access=acl_db->access; - if (want_access) + if (want_access) { String db(buff,sizeof(buff)); db.length(0); @@ -2938,7 +2973,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL))) db.append("ALL PRIVILEGES",14); else if (!(want_access & ~GRANT_ACL)) - db.append("USAGE",5); + db.append("USAGE",5); else { int found=0, cnt; @@ -2954,13 +2989,13 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } } } - db.append (" ON `",5); + db.append(" ON `",5); db.append(acl_db->db); - db.append ("`.* TO '",8); - db.append(lex_user->user.str,lex_user->user.length); - db.append ("'@'",3); + db.append("`.* TO '",8); + db.append(lex_user->user.str,lex_user->user.length); + db.append("'@'",3); db.append(lex_user->host.str, lex_user->host.length); - db.append ('\''); + db.append('\''); if (want_access & GRANT_ACL) db.append(" WITH GRANT OPTION",18); thd->packet.length(0); @@ -2979,7 +3014,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) for (index=0 ; index < hash_tables.records ; index++) { const char *user,*host; - GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index); + GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&hash_tables,index); if (!(user=grant_table->user)) user=""; @@ -2989,44 +3024,54 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!strcmp(lex_user->user.str,user) && !my_strcasecmp(lex_user->host.str,host)) { - want_access=grant_table->privs; - if ((want_access | grant_table->cols) != 0) + ulong table_access= grant_table->privs; + if ((table_access | grant_table->cols) != 0) { String global(buff,sizeof(buff)); global.length(0); global.append("GRANT ",6); - if (test_all_bits(grant_table->privs,(TABLE_ACLS & ~GRANT_ACL))) + if (test_all_bits(table_access, (TABLE_ACLS & ~GRANT_ACL))) global.append("ALL PRIVILEGES",14); - else + else { - int found=0; - ulong j,test_access= (want_access | grant_table->cols) & ~GRANT_ACL; + int found= 0; + ulong j,test_access= (table_access | grant_table->cols) & ~GRANT_ACL; - for (counter=0, j = SELECT_ACL;j <= TABLE_ACLS; counter++,j <<= 1) + for (counter= 0, j= SELECT_ACL; j <= TABLE_ACLS; counter++, j<<= 1) { - if (test_access & j) + if (test_access & j) { if (found) global.append(", ",2); - found = 1; + found= 1; global.append(command_array[counter],command_lengths[counter]); - if (grant_table->cols) + if (grant_table->cols) { - uint found_col=0; + uint found_col= 0; for (uint col_index=0 ; col_index < grant_table->hash_columns.records ; col_index++) { GRANT_COLUMN *grant_column = (GRANT_COLUMN*) hash_element(&grant_table->hash_columns,col_index); - if (grant_column->rights & j) + if (grant_column->rights & j) { - if (!found_col) + if (!found_col) { + found_col= 1; + /* + If we have a duplicated table level privilege, we + must write the access privilege name again. + */ + if (table_access & j) + { + global.append(", ", 2); + global.append(command_array[counter], + command_lengths[counter]); + } global.append(" (",2); - found_col=1; } else global.append(", ",2); @@ -3045,12 +3090,12 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append("`.`",3); global.append(grant_table->tname); global.append("` TO '",6); - global.append(lex_user->user.str,lex_user->user.length); + global.append(lex_user->user.str,lex_user->user.length); global.append("'@'",3); - global.append(lex_user->host.str,lex_user->host.length); + global.append(lex_user->host.str,lex_user->host.length); global.append('\''); - if (want_access & GRANT_ACL) - global.append(" WITH GRANT OPTION",18); + if (table_access & GRANT_ACL) + global.append(" WITH GRANT OPTION",18); thd->packet.length(0); net_store_data(&thd->packet,global.ptr(),global.length()); if (my_net_write(&thd->net,(char*) thd->packet.ptr(), @@ -3063,7 +3108,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) } } - end: +end: VOID(pthread_mutex_unlock(&acl_cache->lock)); pthread_mutex_unlock(&LOCK_grant); diff --git a/sql/sql_acl.h b/sql/sql_acl.h index f3fdf950a12..bf269e5a7e3 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -76,8 +76,8 @@ #define get_rights_for_db(A) (((A) & 63) | (((A) & DB_CHUNK1) >> 4) | (((A) & DB_CHUNK2) >> 6)) #define fix_rights_for_table(A) (((A) & 63) | (((A) & ~63) << 4)) #define get_rights_for_table(A) (((A) & 63) | (((A) & ~63) >> 4)) -#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 7)) -#define get_rights_for_column(A) (((A) & 7) | (((A) & ~7) >> 7)) +#define fix_rights_for_column(A) (((A) & 7) | (((A) & ~7) << 8)) +#define get_rights_for_column(A) (((A) & 7) | ((A) >> 8)) /* prototypes */ From 28e96d95c5813b993f79d317a276810cab7b34ce Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Mon, 23 Jun 2003 20:05:54 +0300 Subject: [PATCH 067/237] Simple code cleanup --- mysql-test/r/innodb.result | 8 ++++---- mysys/mf_pack.c | 26 +++++++++++++++++++------- sql/log_event.cc | 6 +++--- sql/slave.cc | 32 +++++++++++++------------------- sql/sql_repl.cc | 5 ----- sql/sql_select.cc | 14 +++++++------- 6 files changed, 46 insertions(+), 45 deletions(-) diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 9d1c232e830..465d4faf0bc 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -156,7 +156,7 @@ level id parent_id 1 1007 101 optimize table t1; Table Op Msg_type Msg_text -test.t1 optimize error The handler for the table doesn't support optimize +test.t1 optimize status OK show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 0 PRIMARY 1 id A 87 NULL NULL BTREE @@ -180,7 +180,7 @@ create table t1 (a int) type=innodb; insert into t1 values (1), (2); optimize table t1; Table Op Msg_type Msg_text -test.t1 optimize error The handler for the table doesn't support optimize +test.t1 optimize status OK delete from t1 where a = 1; select * from t1; a @@ -712,7 +712,7 @@ world 2 hello 1 optimize table t1; Table Op Msg_type Msg_text -test.t1 optimize error The handler for the table doesn't support optimize +test.t1 optimize status OK show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 0 PRIMARY 1 a A 2 NULL NULL BTREE @@ -1240,7 +1240,7 @@ t1 range c c 5 NULL 1 Using where update t1 set c=a; explain select * from t1 where c between 1 and 10000; table type possible_keys key key_len ref rows Extra -t1 ALL c NULL NULL NULL 29537 Using where +t1 ALL c NULL NULL NULL 27682 Using where drop table t1,t2; create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb; insert into t1 (id) values (null),(null),(null),(null),(null); diff --git a/mysys/mf_pack.c b/mysys/mf_pack.c index 8fba14f626b..b3aa347006e 100644 --- a/mysys/mf_pack.c +++ b/mysys/mf_pack.c @@ -253,15 +253,27 @@ void symdirget(char *dir) } #endif /* USE_SYMDIR */ - /* Unpacks dirname to name that can be used by open... */ - /* Make that last char of to is '/' if from not empty and - from doesn't end in FN_DEVCHAR */ - /* Uses cleanup_dirname and changes ~/.. to home_dir/.. */ - /* Returns length of new directory */ + +/* + Fixes a directroy name so that can be used by open() + + SYNOPSIS + unpack_dirname() + to Store result here. May be = from + from 'Packed' directory name (may contain ~) + + IMPLEMENTATION + Make that last char of to is '/' if from not empty and + from doesn't end in FN_DEVCHAR + Uses cleanup_dirname and changes ~/.. to home_dir/.. + + Changes a UNIX filename to system filename (replaces / with \ on windows) + + RETURN + Length of new directory name (= length of to) +*/ uint unpack_dirname(my_string to, const char *from) - - /* to may be == from */ { uint length,h_length; char buff[FN_REFLEN+1+4],*suffix,*tilde_expansion; diff --git a/sql/log_event.cc b/sql/log_event.cc index 727b2052969..53289888242 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -100,7 +100,7 @@ static void pretty_print_str(String* packet, char* str, int len) static inline char* slave_load_file_stem(char*buf, uint file_id, int event_server_id) { - fn_format(buf,"SQL_LOAD-",slave_load_tmpdir,"",0); /* 4+32); */ + fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME); buf = strend(buf); buf = int10_to_str(::server_id, buf, 10); *buf++ = '-'; @@ -174,16 +174,16 @@ static void cleanup_load_tmpdir() file=dirp->dir_entry+i; if (is_prefix(file->name,"SQL_LOAD-")) { - fn_format(fname,file->name,slave_load_tmpdir,"",0); + fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME); my_delete(fname, MYF(0)); } } my_dirend(dirp); } - #endif + Log_event::Log_event(const char* buf, bool old_format) :temp_buf(0), cached_event_len(0), cache_stmt(0) { diff --git a/sql/slave.cc b/sql/slave.cc index 6c29d1a98bc..fe668900da0 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -134,7 +134,7 @@ int init_slave() goto err; } - if(init_master_info(active_mi,master_info_file,relay_log_info_file, + if (init_master_info(active_mi,master_info_file,relay_log_info_file, !master_host)) { sql_print_error("Failed to initialize the master info structure"); @@ -1777,18 +1777,17 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, pthread_mutex_lock(&data_lock); /* - This function will abort when it notices that - some CHANGE MASTER or RESET MASTER has changed - the master info. To catch this, these commands - modify abort_pos_wait ; we just monitor abort_pos_wait - and see if it has changed. - Why do we have this mechanism instead of simply monitoring slave_running in - the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that the - SQL thread be stopped? This is in case + This function will abort when it notices that some CHANGE MASTER or + RESET MASTER has changed the master info. + To catch this, these commands modify abort_pos_wait ; We just monitor + abort_pos_wait and see if it has changed. + Why do we have this mechanism instead of simply monitoring slave_running + in the loop (we do this too), as CHANGE MASTER/RESET SLAVE require that + the SQL thread be stopped? + This is becasue if someones does: STOP SLAVE;CHANGE MASTER/RESET SLAVE; START SLAVE; - happens very quickly between the moment pthread_cond_wait() wakes up and - the while() is evaluated: in that case slave_running is again 1 when the - while() is evaluated. + the change may happen very quickly and we may not notice that + slave_running briefly switches between 1/0/1. */ init_abort_pos_wait= abort_pos_wait; @@ -1809,7 +1808,7 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, error= -2; //means improper arguments goto err; } - //p points to '.' + /* p points to '.' */ log_name_extension= strtoul(++p, &p_end, 10); /* p_end points to the first invalid character. @@ -1822,14 +1821,9 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, goto err; } - //"compare and wait" main loop + /* The "compare and wait" main loop */ while (!thd->killed && init_abort_pos_wait == abort_pos_wait && - /* - formerly we tested mi->slave_running, but what we care about is - rli->slave_running (because this concerns the SQL thread, while - mi->slave_running concerns the I/O thread). - */ slave_running) { bool pos_reached; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index d0ed1a19d96..ae9bd8b7727 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -68,11 +68,6 @@ static int fake_rotate_event(NET* net, String* packet, char* log_file_name, int4store(header + LOG_POS_OFFSET, 0); packet->append(header, sizeof(header)); - /* - An old comment said talked about a need for splitting the int8store below - into 2 int4store because of a problem with cxx; I can't understand that as - we already use int8store in Rotatel_log_event::write_data(). - */ int8store(buf+R_POS_OFFSET,position); packet->append(buf, ROTATE_HEADER_LEN); packet->append(p,ident_len); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0e8b191e4ef..67bec77e245 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1627,6 +1627,9 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field) key_field->field->table->reginfo.not_exists_optimize=1; } + +#define FT_KEYPART (MAX_REF_PARTS+10) + static void add_ft_keys(DYNAMIC_ARRAY *keyuse_array, JOIN_TAB *stat,COND *cond,table_map usable_tables) @@ -1685,23 +1688,20 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, } } - if (!cond_func || cond_func->key == NO_SUCH_KEY) - return; - - if (!(usable_tables & cond_func->table->map)) + if ((!cond_func || cond_func->key == NO_SUCH_KEY) || + (!(usable_tables & cond_func->table->map))) return; KEYUSE keyuse; - keyuse.table= cond_func->table; keyuse.val = cond_func; keyuse.key = cond_func->key; -#define FT_KEYPART (MAX_REF_PARTS+10) - keyuse.keypart=FT_KEYPART; + keyuse.keypart= FT_KEYPART; keyuse.used_tables=cond_func->key_item()->used_tables(); VOID(insert_dynamic(keyuse_array,(gptr) &keyuse)); } + static int sort_keyuse(KEYUSE *a,KEYUSE *b) { From 039554f38ba5280f431d79d0c64872019d8bdf2a Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Mon, 23 Jun 2003 23:32:07 +0300 Subject: [PATCH 068/237] Changed connect with timeout to use poll() instead if socket() to avoid problems with many open files --- libmysql/libmysql.c | 94 ++++++++++++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index c008d625900..3c8ac9f3387 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -40,14 +40,17 @@ #include #include #ifdef HAVE_SELECT_H -# include +#include #endif #ifdef HAVE_SYS_SELECT_H #include #endif +#ifdef HAVE_POLL +#include #endif +#endif /* !defined(MSDOS) && !defined(__WIN__) */ #ifdef HAVE_SYS_UN_H -# include +#include #endif #if defined(THREAD) && !defined(__WIN__) #include /* because of signal() */ @@ -148,9 +151,12 @@ static MYSQL* spawn_init(MYSQL* parent, const char* host, const char* user, const char* passwd); +#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__)) +static int wait_for_data(my_socket fd, uint timeout); +#endif /**************************************************************************** - A modified version of connect(). connect2() allows you to specify + A modified version of connect(). my_connect() allows you to specify a timeout value, in seconds, that we should wait until we derermine we can't connect to a particular host. If timeout is 0, my_connect() will behave exactly like connect(). @@ -158,17 +164,13 @@ static MYSQL* spawn_init(MYSQL* parent, const char* host, Base version coded by Steve Bernacki, Jr. *****************************************************************************/ -int my_connect(my_socket s, const struct sockaddr *name, uint namelen, +int my_connect(my_socket fd, const struct sockaddr *name, uint namelen, uint timeout) { #if defined(__WIN__) || defined(OS2) || defined(__NETWARE__) - return connect(s, (struct sockaddr*) name, namelen); + return connect(fd, (struct sockaddr*) name, namelen); #else int flags, res, s_err; - SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); - fd_set sfds; - struct timeval tv; - time_t start_time, now_time; /* If they passed us a timeout of zero, we should behave @@ -176,30 +178,68 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen, */ if (timeout == 0) - return connect(s, (struct sockaddr*) name, namelen); + return connect(fd, (struct sockaddr*) name, namelen); - flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */ + flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */ #ifdef O_NONBLOCK - fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */ + fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */ #endif - res = connect(s, (struct sockaddr*) name, namelen); - s_err = errno; /* Save the error... */ - fcntl(s, F_SETFL, flags); + res= connect(fd, (struct sockaddr*) name, namelen); + s_err= errno; /* Save the error... */ + fcntl(fd, F_SETFL, flags); if ((res != 0) && (s_err != EINPROGRESS)) { - errno = s_err; /* Restore it */ + errno= s_err; /* Restore it */ return(-1); } if (res == 0) /* Connected quickly! */ return(0); + return wait_for_data(fd, timeout); +#endif +} + + +/* + Wait up to timeout seconds for a connection to be established. + + We prefer to do this with poll() as there is no limitations with this. + If not, we will use select() +*/ + +#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__)) + +static int wait_for_data(my_socket fd, uint timeout) +{ +#ifdef HAVE_POLL + struct pollfd ufds; + int res; + + ufds.fd= fd; + ufds.events= POLLIN | POLLPRI; + if (!(res= poll(&ufds, 1, (int) timeout*1000))) + { + errno= EINTR; + return -1; + } + if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI))) + return -1; + return 0; +#else + SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); + fd_set sfds; + struct timeval tv; + time_t start_time, now_time; + int res, s_err; + + if (fd >= FD_SETSIZE) /* Check if wrong error */ + return 0; /* Can't use timeout */ /* - Otherwise, our connection is "in progress." We can use - the select() call to wait up to a specified period of time - for the connection to suceed. If select() returns 0 - (after waiting howevermany seconds), our socket never became - writable (host is probably unreachable.) Otherwise, if + Our connection is "in progress." We can use the select() call to wait + up to a specified period of time for the connection to suceed. + If select() returns 0 (after waiting howevermany seconds), our socket + never became writable (host is probably unreachable.) Otherwise, if select() returns 1, then one of two conditions exist: 1. An error occured. We use getsockopt() to check for this. @@ -212,7 +252,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen, */ FD_ZERO(&sfds); - FD_SET(s, &sfds); + FD_SET(fd, &sfds); /* select could be interrupted by a signal, and if it is, the timeout should be adjusted and the select restarted @@ -226,10 +266,10 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen, tv.tv_sec = (long) timeout; tv.tv_usec = 0; #if defined(HPUX10) && defined(THREAD) - if ((res = select(s+1, NULL, (int*) &sfds, NULL, &tv)) > 0) + if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0) break; #else - if ((res = select(s+1, NULL, &sfds, NULL, &tv)) > 0) + if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0) break; #endif if (res == 0) /* timeout */ @@ -247,7 +287,7 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen, */ s_err=0; - if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) return(-1); if (s_err) @@ -256,9 +296,9 @@ int my_connect(my_socket s, const struct sockaddr *name, uint namelen, return(-1); /* but return an error... */ } return (0); /* ok */ - -#endif +#endif /* HAVE_POLL */ } +#endif /* defined(__WIN__) || defined(OS2) || defined(__NETWARE__) */ /* Create a named pipe connection From 3007290f832e0fda79780e0b4316f1f55a6c952c Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Tue, 24 Jun 2003 10:53:21 +0500 Subject: [PATCH 069/237] Another bugfix for #615 Looks a bit nicer than previous one --- mysql-test/r/insert.result | 10 ++++++++++ mysql-test/t/insert.test | 12 ++++++++++++ sql/field.h | 6 ++++-- sql/field_conv.cc | 6 ++---- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 69b790ff35b..d019cfcbfa9 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -58,6 +58,16 @@ skr 2 test 1 test 2 drop table t1; +create table t1 (id int NOT NULL DEFAULT 8); +insert into t1 values(NULL); +Column 'id' cannot be null +insert into t1 values (1), (NULL), (2); +select * from t1; +id +1 +8 +2 +drop table t1; drop database if exists foo; create database foo; use foo; diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test index 9b06b522028..be585157e63 100644 --- a/mysql-test/t/insert.test +++ b/mysql-test/t/insert.test @@ -50,6 +50,17 @@ insert into t1 values ('rts',NULL),('rts',NULL),('test',NULL); select * from t1; drop table t1; +# +#Test of behaviour with INSERT VALUES (NULL) +# + +create table t1 (id int NOT NULL DEFAULT 8); +-- error 1048 +insert into t1 values(NULL); +insert into t1 values (1), (NULL), (2); +select * from t1; +drop table t1; + # # Test of mysqld crash with fully qualified column names # @@ -60,3 +71,4 @@ use foo; create table t1 (c int); insert into foo.t1 set foo.t1.c = '1'; drop database foo; + diff --git a/sql/field.h b/sql/field.h index e63802d8c00..3186f9f5275 100644 --- a/sql/field.h +++ b/sql/field.h @@ -72,10 +72,12 @@ public: virtual void reset_fields() {} virtual void set_default() { - memcpy(ptr, ptr + table->rec_buff_length, pack_length()); + my_ptrdiff_t offset = (my_ptrdiff_t) (table->record[2] - + table->record[0]); + memcpy(ptr, ptr + offset, pack_length()); if (null_ptr) *null_ptr= ((*null_ptr & (uchar) ~null_bit) | - null_ptr[table->rec_buff_length] & null_bit); + null_ptr[offset] & null_bit); } virtual bool binary() const { return 1; } virtual bool zero_pack() const { return 1; } diff --git a/sql/field_conv.cc b/sql/field_conv.cc index a32a635ac05..ce67455881b 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -118,10 +118,9 @@ set_field_to_null(Field *field) field->reset(); return 0; } - field->reset(); + field->set_default(); if (current_thd->count_cuted_fields) { - field->set_default(); current_thd->cuted_fields++; // Increment error counter return 0; } @@ -171,12 +170,11 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) ((Field_timestamp*) field)->set_time(); return 0; // Ok to set time to NULL } - field->reset(); + field->set_default(); if (field == field->table->next_number_field) return 0; // field is set in handler.cc if (current_thd->count_cuted_fields) { - field->set_default(); current_thd->cuted_fields++; // Increment error counter return 0; } From 383d354c5c0e0460fe8d63c07374ec08d8be8a50 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Tue, 24 Jun 2003 17:07:43 +0500 Subject: [PATCH 070/237] Test case for bug #666 --- mysql-test/r/func_str.result | 13 +++++++++++++ mysql-test/t/func_str.test | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 1a4cb9217e4..09818c14462 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -234,3 +234,16 @@ INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf'); SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password"); 1 DROP TABLE t1; +CREATE TABLE t1 ( +wid int(10) unsigned NOT NULL auto_increment, +data_podp date default NULL, +status_wnio enum('nowy','podp','real','arch') NOT NULL default 'nowy', +PRIMARY KEY(wid), +); +INSERT INTO t1 VALUES (8,NULL,'real'); +INSERT INTO t1 VALUES (9,NULL,'nowy'); +SELECT elt(status_wnio,data_podp) FROM t1 GROUP BY wid; +elt(status_wnio,data_podp) +NULL +NULL +DROP TABLE t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 118de6cd01e..476629f98d3 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -125,3 +125,15 @@ CREATE TABLE t1 (id int(11) NOT NULL auto_increment, tmp text NOT NULL, KEY id ( INSERT INTO t1 VALUES (1, 'a545f661efdd1fb66fdee3aab79945bf'); SELECT 1 FROM t1 WHERE tmp=AES_DECRYPT(tmp,"password"); DROP TABLE t1; + +CREATE TABLE t1 ( + wid int(10) unsigned NOT NULL auto_increment, + data_podp date default NULL, + status_wnio enum('nowy','podp','real','arch') NOT NULL default 'nowy', + PRIMARY KEY(wid), +); + +INSERT INTO t1 VALUES (8,NULL,'real'); +INSERT INTO t1 VALUES (9,NULL,'nowy'); +SELECT elt(status_wnio,data_podp) FROM t1 GROUP BY wid; +DROP TABLE t1; From dc704a2c20f3050f38a9f9dd214cb1d2b148e277 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 25 Jun 2003 11:16:06 +0200 Subject: [PATCH 071/237] - reverted change from AC_CONFIG_HEADERS to AM_CONFIG_HEADER in configure.in again - even though the automake docs consider AM_CONFIG_HEADER obsolete, it currently still breaks for too many people to justify this change at the moment. --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index d45aecdf494..a33ccd4a311 100644 --- a/configure.in +++ b/configure.in @@ -5,7 +5,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! AM_INIT_AUTOMAKE(mysql, 4.0.14) -AC_CONFIG_HEADERS(config.h) +AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 DOT_FRM_VERSION=6 From 45b3c643be302a1710bc874c8af8ea743e5e46c1 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Wed, 25 Jun 2003 17:15:33 +0500 Subject: [PATCH 072/237] Testcase for #674 added --- mysql-test/r/sel000100.result | 10 ++++++++++ mysql-test/t/sel000100.test | 15 +++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/mysql-test/r/sel000100.result b/mysql-test/r/sel000100.result index f9234815a2b..3ffa4004b84 100644 --- a/mysql-test/r/sel000100.result +++ b/mysql-test/r/sel000100.result @@ -26,3 +26,13 @@ ORDER BY link; key_link_id link NULL NULL drop table t1,t2; +CREATE TABLE t1 ( +html varchar(5) default NULL, +rin int(11) default '0', +out int(11) default '0' +) TYPE=MyISAM; +INSERT INTO t1 VALUES ('1',1,0); +SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; +html prod +1 0.00 +drop table t1; diff --git a/mysql-test/t/sel000100.test b/mysql-test/t/sel000100.test index cedb78b17e7..d587fa4ebd0 100644 --- a/mysql-test/t/sel000100.test +++ b/mysql-test/t/sel000100.test @@ -29,3 +29,18 @@ GROUP BY t1.id ORDER BY link; drop table t1,t2; + +# +# test case for #674 +# +CREATE TABLE t1 ( + html varchar(5) default NULL, + rin int(11) default '0', + out int(11) default '0' +) TYPE=MyISAM; + +INSERT INTO t1 VALUES ('1',1,0); + +SELECT DISTINCT html,SUM(out)/(SUM(rin)+1) as 'prod' FROM t1 GROUP BY rin; + +drop table t1; From 1d93c8f55098a3cf7279136e047ae9a005005182 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Wed, 25 Jun 2003 18:36:52 +0300 Subject: [PATCH 073/237] Fix for a bug which results in "Unknown Error". Query should actually return empty result set, but currently can't, as it attempts to store NULL in NOT NULL field, because that is a match made by self join conditions. --- sql/sql_select.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0e8b191e4ef..c2c4070956c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -969,7 +969,14 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, group ? group : order, select_limit, thd->select_limit)) - goto err; /* purecov: inspected */ + { + if (!join.join_tab[join.const_tables].select->quick) + error= return_zero_rows(&join, result, tables, fields, + 0, select_options, + "Impossible WHERE noticed after reading const tables", + having,procedure); + goto err; + } } join.having=having; // Actually a parameter thd->proc_info="Sending data"; From 5722ae6627904558c9207083e82300049aa0b579 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Wed, 25 Jun 2003 21:11:23 -0400 Subject: [PATCH 074/237] fixed bug with type of user variables (bug #551) --- BitKeeper/etc/logging_ok | 1 + mysql-test/r/user_var.result | 8 ++++++++ mysql-test/t/user_var.test | 6 ++++++ sql/item_func.cc | 1 + 4 files changed, 16 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index a6699f7c515..705b336440b 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -35,5 +35,6 @@ serg@build.mysql2.com serg@serg.mysql.com serg@sergbook.mysql.com sinisa@rhols221.adsl.netsonic.fi +vva@eagle.mysql.r18.ru walrus@mysql.com zak@balfor.local diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index e06a113bd29..8abdb40399a 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -14,3 +14,11 @@ table type possible_keys key key_len ref rows Extra t1 index NULL i 4 NULL 3 where used; Using index table type possible_keys key key_len ref rows Extra t1 ref i i 4 const 1 where used +@a:=10 @b:=1 @a > @b @a < @b +10 1 1 0 +@a:="10" @b:="1" @a > @b @a < @b +10 1 1 0 +@a:=10 @b:=2 @a > @b @a < @b +10 2 1 0 +@a:="10" @b:="2" @a > @b @a < @b +10 2 0 1 diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 70283446fb3..3103de2dac5 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -17,3 +17,9 @@ explain select * from t1 where @vv1:=@vv1+1 and i=@vv1; explain select @vv1:=i from t1 where i=@vv1; explain select * from t1 where i=@vv1; drop table t1,t2; + +# Check types of variables +select @a:=10, @b:=1, @a > @b, @a < @b; +select @a:="10", @b:="1", @a > @b, @a < @b; +select @a:=10, @b:=2, @a > @b, @a < @b; +select @a:="10", @b:="2", @a > @b, @a < @b; diff --git a/sql/item_func.cc b/sql/item_func.cc index 723585be0b1..217768db2c5 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1676,6 +1676,7 @@ bool Item_func_set_user_var::fix_fields(THD *thd,TABLE_LIST *tables) if (Item_func::fix_fields(thd,tables) || !(entry= get_variable(&thd->user_vars, name, 1))) return 1; + entry->type= cached_result_type; entry->update_query_id=thd->query_id; return 0; } From 7655f05dc2377b3df8b9fabb0e622781f65d5b60 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Thu, 26 Jun 2003 05:38:19 +0300 Subject: [PATCH 075/237] LEFT JOIN optimization: Change LEFT JOIN to normal join if possible --- mysql-test/r/select.result | 34 +++++++++++++++++++++++++++++-- mysql-test/t/select.test | 14 +++++++++++++ sql/item.h | 17 ++++++++++++++++ sql/item_cmpfunc.cc | 41 ++++++++++++++++++++++++++++---------- sql/item_cmpfunc.h | 18 ++++++++++++----- sql/item_func.cc | 14 ++++++++++--- sql/item_func.h | 9 +++++++-- sql/item_strfunc.cc | 17 +++++++++------- sql/sql_base.cc | 16 +++++++++++---- 9 files changed, 147 insertions(+), 33 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index a4c2533ec1a..811c396ea67 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2569,16 +2569,46 @@ fld1 fld1 250503 250505 250504 250505 250505 250505 +insert into t2 (fld1, companynr) values (999999,99); select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; companynr companyname +99 NULL +select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null; +count(*) +1199 explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; table type possible_keys key key_len ref rows Extra -t2 ALL NULL NULL NULL NULL 1199 +t2 ALL NULL NULL NULL NULL 1200 t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null; table type possible_keys key key_len ref rows Extra t4 ALL NULL NULL NULL NULL 12 -t2 ALL NULL NULL NULL NULL 1199 Using where; Not exists +t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists +delete from t2 where fld1=999999; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; +table type possible_keys key key_len ref rows Extra +t2 ALL NULL NULL NULL NULL 1199 Using where +t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; +table type possible_keys key key_len ref rows Extra +t2 ALL NULL NULL NULL NULL 1199 Using where +t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; +table type possible_keys key key_len ref rows Extra +t2 ALL NULL NULL NULL NULL 1199 Using where +t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; +table type possible_keys key key_len ref rows Extra +t4 ALL NULL NULL NULL NULL 12 +t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0; +table type possible_keys key key_len ref rows Extra +t4 ALL PRIMARY NULL NULL NULL 12 +t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0; +table type possible_keys key key_len ref rows Extra +t4 ALL NULL NULL NULL NULL 12 +t2 ALL NULL NULL NULL NULL 1199 Using where select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; companynr companynr 37 36 diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index de90eeec2e8..c2e451ea7f3 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1527,10 +1527,24 @@ select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 25 # # Test of left join. # +insert into t2 (fld1, companynr) values (999999,99); select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; +select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null; explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null; +delete from t2 where fld1=999999; + +# +# Test left join optimization + +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; +# Following can't be optimized +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0; # # Joins with forms. diff --git a/sql/item.h b/sql/item.h index 09d428509d0..1631bf76135 100644 --- a/sql/item.h +++ b/sql/item.h @@ -71,7 +71,24 @@ public: virtual double val_result() { return val(); } virtual longlong val_int_result() { return val_int(); } virtual String *str_result(String* tmp) { return val_str(tmp); } + /* bit map of tables used by item */ virtual table_map used_tables() const { return (table_map) 0L; } + /* + Return table map of tables that can't be NULL tables (tables that are + used in a context where if they would contain a NULL row generated + by a LEFT or RIGHT join, the item would not be true). + This expression is used on WHERE item to determinate if a LEFT JOIN can be + converted to a normal join. + Generally this function should return used_tables() if the function + would return null if any of the arguments are null + As this is only used in the beginning of optimization, the value don't + have to be updated in update_used_tables() + */ + virtual table_map not_null_tables() const { return used_tables(); } + /* + Returns true if this is a simple constant item like an integer, not + a constant expression + */ virtual bool basic_const_item() const { return 0; } virtual Item *new_item() { return 0; } /* Only for const items */ virtual cond_result eq_cmp_result() const { return COND_OK; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 3344f2bc01d..770fe3c0232 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -292,10 +292,12 @@ void Item_func_interval::fix_length_and_dec() } } maybe_null=0; max_length=2; - used_tables_cache|=item->used_tables(); + used_tables_cache|= item->used_tables(); + not_null_tables_cache&= item->not_null_tables(); with_sum_func= with_sum_func || item->with_sum_func; } + void Item_func_interval::split_sum_func(List &fields) { if (item->with_sum_func && item->type() != SUM_FUNC_ITEM) @@ -1073,8 +1075,9 @@ void Item_func_in::fix_length_and_dec() } maybe_null= item->maybe_null; max_length=2; - used_tables_cache|=item->used_tables(); - const_item_cache&=item->const_item(); + used_tables_cache|= item->used_tables(); + not_null_tables_cache&= item->not_null_tables(); + const_item_cache&= item->const_item(); } @@ -1174,14 +1177,21 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) char buff[sizeof(char*)]; // Max local vars in function used_tables_cache=0; const_item_cache=0; + /* + and_table_cache is the value that Item_cond_or() returns for + not_null_tables() + */ + and_tables_cache= ~(table_map) 0; if (thd && check_stack_overrun(thd,buff)) return 0; // Fatal error flag is set! while ((item=li++)) { + table_map tmp_table_map; while (item->type() == Item::COND_ITEM && ((Item_cond*) item)->functype() == functype()) { // Identical function + li.replace(((Item_cond*) item)->list); ((Item_cond*) item)->list.empty(); #ifdef DELETE_ITEMS @@ -1193,9 +1203,12 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) item->top_level_item(); if (item->fix_fields(thd,tables)) return 1; /* purecov: inspected */ - used_tables_cache|=item->used_tables(); - with_sum_func= with_sum_func || item->with_sum_func; - const_item_cache&=item->const_item(); + used_tables_cache|= item->used_tables(); + tmp_table_map= item->not_null_tables(); + not_null_tables_cache|= tmp_table_map; + and_tables_cache&= tmp_table_map; + const_item_cache&= item->const_item(); + with_sum_func= with_sum_func || item->with_sum_func; if (item->maybe_null) maybe_null=1; } @@ -1234,17 +1247,19 @@ Item_cond::used_tables() const return used_tables_cache; } + void Item_cond::update_used_tables() { - used_tables_cache=0; - const_item_cache=1; List_iterator_fast li(list); Item *item; + + used_tables_cache=0; + const_item_cache=1; while ((item=li++)) { item->update_used_tables(); - used_tables_cache|=item->used_tables(); - const_item_cache&= item->const_item(); + used_tables_cache|= item->used_tables(); + const_item_cache&= item->const_item(); } } @@ -1348,12 +1363,16 @@ Item *and_expressions(Item *a, Item *b, Item **org_item) { Item_cond *res; if ((res= new Item_cond_and(a, (Item*) b))) + { res->used_tables_cache= a->used_tables() | b->used_tables(); + res->not_null_tables_cache= a->not_null_tables() | b->not_null_tables(); + } return res; } if (((Item_cond_and*) a)->add((Item*) b)) return 0; ((Item_cond_and*) a)->used_tables_cache|= b->used_tables(); + ((Item_cond_and*) a)->not_null_tables_cache|= b->not_null_tables(); return a; } @@ -1489,6 +1508,8 @@ Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) max_length=1; decimals=0; binary=args[0]->binary || args[1]->binary; used_tables_cache=args[0]->used_tables() | args[1]->used_tables(); + not_null_tables_cache= (args[0]->not_null_tables() | + args[1]->not_null_tables()); const_item_cache=args[0]->const_item() && args[1]->const_item(); if (!regex_compiled && args[1]->const_item()) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index f7ade97940c..536ac9dc3d4 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -204,7 +204,7 @@ public: enum Item_result result_type () const { return cached_result_type; } void fix_length_and_dec(); const char *func_name() const { return "ifnull"; } - unsigned int size_of() { return sizeof(*this);} + table_map not_null_tables() const { return 0; } }; @@ -224,7 +224,7 @@ public: } void fix_length_and_dec(); const char *func_name() const { return "if"; } - unsigned int size_of() { return sizeof(*this);} + table_map not_null_tables() const { return 0; } }; @@ -239,7 +239,7 @@ public: enum Item_result result_type () const { return cached_result_type; } void fix_length_and_dec(); const char *func_name() const { return "nullif"; } - unsigned int size_of() { return sizeof(*this);} + table_map not_null_tables() const { return 0; } }; @@ -254,9 +254,10 @@ public: void fix_length_and_dec(); enum Item_result result_type () const { return cached_result_type; } const char *func_name() const { return "coalesce"; } - unsigned int size_of() { return sizeof(*this);} + table_map not_null_tables() const { return 0; } }; + class Item_func_case :public Item_func { Item * first_expr, *else_expr; @@ -270,6 +271,7 @@ public: String *val_str(String *); void fix_length_and_dec(); void update_used_tables(); + table_map not_null_tables() const { return 0; } enum Item_result result_type () const { return cached_result_type; } const char *func_name() const { return "case"; } void print(String *str); @@ -479,10 +481,12 @@ public: } } } + table_map not_null_tables() const { return 0; } optimize_type select_optimize() const { return OPTIMIZE_NULL; } unsigned int size_of() { return sizeof(*this);} }; + class Item_func_isnotnull :public Item_bool_func { public: @@ -495,9 +499,10 @@ public: } const char *func_name() const { return "isnotnull"; } optimize_type select_optimize() const { return OPTIMIZE_NULL; } - unsigned int size_of() { return sizeof(*this);} + table_map not_null_tables() const { return 0; } }; + class Item_func_like :public Item_bool_func2 { char escape; @@ -572,6 +577,8 @@ class Item_cond :public Item_bool_func protected: List list; bool abort_on_null; + table_map and_tables_cache; + public: /* Item_cond() is only used to create top level items */ Item_cond() : Item_bool_func(), abort_on_null(1) { const_item_cache=0; } @@ -611,6 +618,7 @@ public: enum Functype functype() const { return COND_OR_FUNC; } longlong val_int(); const char *func_name() const { return "or"; } + table_map not_null_tables() const { return and_tables_cache; } }; diff --git a/sql/item_func.cc b/sql/item_func.cc index e847b203006..23bec0c3c81 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -61,7 +61,7 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables) Item **arg,**arg_end; char buff[STACK_BUFF_ALLOC]; // Max argument in function binary=0; - used_tables_cache=0; + used_tables_cache= not_null_tables_cache= 0; const_item_cache=1; if (thd && check_stack_overrun(thd,buff)) @@ -78,8 +78,9 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables) if (item->binary) binary=1; with_sum_func= with_sum_func || item->with_sum_func; - used_tables_cache|=item->used_tables(); - const_item_cache&= item->const_item(); + used_tables_cache|= item->used_tables(); + not_null_tables_cache|= item->not_null_tables(); + const_item_cache&= item->const_item(); } } fix_length_and_dec(); @@ -122,6 +123,13 @@ table_map Item_func::used_tables() const return used_tables_cache; } + +table_map Item_func::not_null_tables() const +{ + return not_null_tables_cache; +} + + void Item_func::print(String *str) { str->append(func_name()); diff --git a/sql/item_func.h b/sql/item_func.h index 68e5335dc7e..8a4cace0b87 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -34,7 +34,7 @@ protected: Item **args,*tmp_arg[2]; public: uint arg_count; - table_map used_tables_cache; + table_map used_tables_cache, not_null_tables_cache; bool const_item_cache; enum Functype { UNKNOWN_FUNC,EQ_FUNC,EQUAL_FUNC,NE_FUNC,LT_FUNC,LE_FUNC, GE_FUNC,GT_FUNC,FT_FUNC, @@ -97,6 +97,7 @@ public: bool fix_fields(THD *,struct st_table_list *); void make_field(Send_field *field); table_map used_tables() const; + table_map not_null_tables() const; void update_used_tables(); bool eq(const Item *item, bool binary_cmp) const; virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; } @@ -588,7 +589,8 @@ public: void split_sum_func(List &fields); void update_used_tables() { - item->update_used_tables() ; Item_func::update_used_tables(); + item->update_used_tables(); + Item_func::update_used_tables(); used_tables_cache|= item->used_tables(); const_item_cache&= item->const_item(); } @@ -597,6 +599,7 @@ public: { maybe_null=0; max_length=3; used_tables_cache|= item->used_tables(); + not_null_tables_cache&= item->not_null_tables(); const_item_cache&= item->const_item(); with_sum_func= with_sum_func || item->with_sum_func; } @@ -736,6 +739,7 @@ public: return res; } Item_result result_type () const { return udf.result_type(); } + table_map not_null_tables() const { return 0; } unsigned int size_of() { return sizeof(*this);} }; @@ -969,6 +973,7 @@ public: } enum Functype functype() const { return FT_FUNC; } void update_used_tables() {} + table_map not_null_tables() const { return 0; } bool fix_fields(THD *thd,struct st_table_list *tlist); bool eq(const Item *, bool binary_cmp) const; longlong val_int() { return val()!=0.0; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 208be1ecd7f..20496a47671 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -606,9 +606,10 @@ void Item_func_concat_ws::fix_length_and_dec() max_length=MAX_BLOB_WIDTH; maybe_null=1; } - used_tables_cache|=separator->used_tables(); - const_item_cache&=separator->const_item(); - with_sum_func= with_sum_func || separator->with_sum_func; + used_tables_cache|= separator->used_tables(); + not_null_tables_cache&= separator->not_null_tables(); + const_item_cache&= separator->const_item(); + with_sum_func= with_sum_func || separator->with_sum_func; } void Item_func_concat_ws::update_used_tables() @@ -1509,8 +1510,9 @@ void Item_func_elt::fix_length_and_dec() } maybe_null=1; // NULL if wrong first arg with_sum_func= with_sum_func || item->with_sum_func; - used_tables_cache|=item->used_tables(); - const_item_cache&=item->const_item(); + used_tables_cache|= item->used_tables(); + not_null_tables_cache&= item->not_null_tables(); + const_item_cache&= item->const_item(); } @@ -1591,8 +1593,9 @@ void Item_func_make_set::fix_length_and_dec() max_length=arg_count-1; for (uint i=1 ; i < arg_count ; i++) max_length+=args[i]->max_length; - used_tables_cache|=item->used_tables(); - const_item_cache&=item->const_item(); + used_tables_cache|= item->used_tables(); + not_null_tables_cache&= item->not_null_tables(); + const_item_cache&= item->const_item(); with_sum_func= with_sum_func || item->with_sum_func; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3bfd5e14d43..43718e5d93b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1903,11 +1903,11 @@ bool setup_tables(TABLE_LIST *tables) table->used_fields=0; table->const_table=0; - table->outer_join=table->null_row=0; + table->null_row=0; table->status=STATUS_NO_RECORD; table->keys_in_use_for_query= table->keys_in_use; table->used_keys= table->keys_for_keyread; - table->maybe_null=test(table->outer_join=table_list->outer_join); + table->maybe_null=test(table->outer_join= table_list->outer_join); table->tablenr=tablenr; table->map= (table_map) 1 << tablenr; table->force_index= table_list->force_index; @@ -2027,6 +2027,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) { + table_map not_null_tables= 0; DBUG_ENTER("setup_conds"); thd->set_query_id=1; thd->cond_count=0; @@ -2036,6 +2037,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) thd->where="where clause"; if ((*conds)->fix_fields(thd,tables)) DBUG_RETURN(1); + not_null_tables= (*conds)->not_null_tables(); } /* Check if we are using outer joins */ @@ -2049,9 +2051,15 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) DBUG_RETURN(1); thd->cond_count++; - /* If it's a normal join, add the ON/USING expression to the WHERE */ - if (!table->outer_join) + /* + If it's a normal join or a LEFT JOIN which can be optimized away + add the ON/USING expression to the WHERE + */ + if (!table->outer_join || + ((table->table->map & not_null_tables) && + !(specialflag & SPECIAL_NO_NEW_FUNC))) { + table->outer_join= 0; if (!(*conds=and_conds(*conds, table->on_expr))) DBUG_RETURN(1); table->on_expr=0; From 5f556f11e0e0ef0daefd41829cd400cc7addb583 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Thu, 26 Jun 2003 07:56:55 +0300 Subject: [PATCH 076/237] Fixed memory allocation in Unique to not allocate too much memory --- myisam/mi_info.c | 12 +++++++----- mysys/tree.c | 5 +++++ sql/net_serv.cc | 3 +++ sql/sql_class.h | 42 ++++++++++++++++++++++-------------------- sql/uniques.cc | 6 +++--- 5 files changed, 40 insertions(+), 28 deletions(-) diff --git a/myisam/mi_info.c b/myisam/mi_info.c index 32767e73bb1..f4eace198f9 100644 --- a/myisam/mi_info.c +++ b/myisam/mi_info.c @@ -80,15 +80,17 @@ int mi_status(MI_INFO *info, register MI_ISAMINFO *x, uint flag) (HA_OPTION_PACK_RECORD | HA_OPTION_COMPRESS_RECORD)) ? 0L : share->base.pack_reclength); x->sortkey= -1; /* No clustering */ - /* The following should be included even if we are not compiling with - USE_RAID as the client must be able to request it! */ x->rec_per_key = share->state.rec_per_key_part; - x->raid_type= share->base.raid_type; - x->raid_chunks= share->base.raid_chunks; - x->raid_chunksize= share->base.raid_chunksize; x->key_map = share->state.key_map; x->data_file_name = share->data_file_name; x->index_file_name = share->index_file_name; + /* + The following should be included even if we are not compiling with + USE_RAID as the client must be able to request it! + */ + x->raid_type= share->base.raid_type; + x->raid_chunks= share->base.raid_chunks; + x->raid_chunksize= share->base.raid_chunksize; } if ((flag & HA_STATUS_TIME) && !my_fstat(info->dfile,&state,MYF(0))) x->update_time=state.st_mtime; diff --git a/mysys/tree.c b/mysys/tree.c index ea5cf79f084..2b5ea717809 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -90,6 +90,11 @@ void init_tree(TREE *tree, uint default_alloc_size, uint memory_limit, if (!free_element && size >= 0 && ((uint) size <= sizeof(void*) || ((uint) size & (sizeof(void*)-1)))) { + /* + We know that the data doesn't have to be aligned (like if the key + contains a double), so we can store the data combined with the + TREE_ELEMENT. + */ tree->offset_to_key=sizeof(TREE_ELEMENT); /* Put key after element */ /* Fix allocation size so that we don't lose any memory */ default_alloc_size/=(sizeof(TREE_ELEMENT)+size); diff --git a/sql/net_serv.cc b/sql/net_serv.cc index a8bc559e3a0..13f786e0e75 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -21,6 +21,9 @@ Read packets are reallocated dynamicly when reading big packets. Each logical packet has the following pre-info: 3 byte length & 1 byte package-number. + + This file needs to be written in C as it's used by the libmysql client as a + C file. */ #ifdef __WIN__ diff --git a/sql/sql_class.h b/sql/sql_class.h index a8a24451ecc..3246f77c77a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -781,11 +781,12 @@ class Unique :public Sql_alloc TREE tree; byte *record_pointers; bool flush(); + uint size; public: ulong elements; Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, - uint size, ulong max_in_memory_size_arg); + uint size_arg, ulong max_in_memory_size_arg); ~Unique(); inline bool unique_add(gptr ptr) { @@ -800,26 +801,27 @@ public: friend int unique_write_to_ptrs(gptr key, element_count count, Unique *unique); }; - class multi_delete : public select_result { - TABLE_LIST *delete_tables, *table_being_deleted; - Unique **tempfiles; - THD *thd; - ha_rows deleted; - uint num_of_tables; - int error; - bool do_delete, transactional_tables, log_delayed, normal_tables; - public: - multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables); - ~multi_delete(); - int prepare(List &list); - bool send_fields(List &list, +class multi_delete : public select_result +{ + TABLE_LIST *delete_tables, *table_being_deleted; + Unique **tempfiles; + THD *thd; + ha_rows deleted; + uint num_of_tables; + int error; + bool do_delete, transactional_tables, log_delayed, normal_tables; +public: + multi_delete(THD *thd, TABLE_LIST *dt, uint num_of_tables); + ~multi_delete(); + int prepare(List &list); + bool send_fields(List &list, uint flag) { return 0; } - bool send_data(List &items); - bool initialize_tables (JOIN *join); - void send_error(uint errcode,const char *err); - int do_deletes (bool from_send_error); - bool send_eof(); - }; + bool send_data(List &items); + bool initialize_tables (JOIN *join); + void send_error(uint errcode,const char *err); + int do_deletes (bool from_send_error); + bool send_eof(); +}; class multi_update : public select_result { diff --git a/sql/uniques.cc b/sql/uniques.cc index ed256a4b791..d00893a8605 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -49,8 +49,8 @@ int unique_write_to_ptrs(gptr key, element_count count, Unique *unique) } Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, - uint size, ulong max_in_memory_size_arg) - :max_in_memory_size(max_in_memory_size_arg),elements(0) + uint size_arg, ulong max_in_memory_size_arg) + :max_in_memory_size(max_in_memory_size_arg), size(size_arg), elements(0) { my_b_clear(&file); init_tree(&tree, max_in_memory_size / 16, 0, size, comp_func, 0, NULL, @@ -101,7 +101,7 @@ bool Unique::get(TABLE *table) { /* Whole tree is in memory; Don't use disk if you don't need to */ if ((record_pointers=table->record_pointers= (byte*) - my_malloc(tree.size_of_element * tree.elements_in_tree, MYF(0)))) + my_malloc(size * tree.elements_in_tree, MYF(0)))) { (void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs, this, left_root_right); From 7d43750eb629a942527a9ccd9a05463ba73d4664 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Thu, 26 Jun 2003 12:47:36 +0500 Subject: [PATCH 077/237] Fix bug #673: MySQL 4.0.13 no SSL connection with mysql client possible --- sql/sql_acl.cc | 7 +++++-- vio/viossl.c | 6 ++---- vio/viosslfactories.c | 13 ++++++++++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f01248bb682..72c8d4aaf38 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -546,7 +546,9 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, We need to check for absence of SSL because without SSL we should reject connection. */ - if (vio_type(vio) == VIO_TYPE_SSL && SSL_get_peer_certificate(vio->ssl_)) + if (vio_type(vio) == VIO_TYPE_SSL && + SSL_get_verify_result(vio->ssl_) == X509_V_OK && + SSL_get_peer_certificate(vio->ssl_)) user_access=acl_user->access; break; case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */ @@ -554,7 +556,8 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, We need to check for absence of SSL because without SSL we should reject connection. */ - if (vio_type(vio) == VIO_TYPE_SSL) + if (vio_type(vio) == VIO_TYPE_SSL && + SSL_get_verify_result(vio->ssl_) == X509_V_OK) { if (acl_user->ssl_cipher) { diff --git a/vio/viossl.c b/vio/viossl.c index 834343a77d9..fc95b0755ce 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -287,8 +287,7 @@ int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout); SSL_set_fd(vio->ssl_,vio->sd); SSL_set_accept_state(vio->ssl_); - if (SSL_do_handshake(vio->ssl_) < 1 || - SSL_get_verify_result(vio->ssl_) != X509_V_OK) + if (SSL_do_handshake(vio->ssl_) < 1) { DBUG_PRINT("error", ("SSL_do_handshake failure")); report_errors(); @@ -361,8 +360,7 @@ int sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) SSL_SESSION_set_timeout(SSL_get_session(vio->ssl_), timeout); SSL_set_fd (vio->ssl_, vio->sd); SSL_set_connect_state(vio->ssl_); - if (SSL_do_handshake(vio->ssl_) < 1 || - SSL_get_verify_result(vio->ssl_) != X509_V_OK) + if (SSL_do_handshake(vio->ssl_) < 1) { DBUG_PRINT("error", ("SSL_do_handshake failure")); report_errors(); diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 31bc457d1ae..72ac915d14e 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -178,6 +178,11 @@ vio_verify_callback(int ok, X509_STORE_CTX *ctx) /************************ VioSSLConnectorFd **********************************/ +/* + TODO: + Add option --verify to mysql to be able to change verification mode +*/ + struct st_VioSSLConnectorFd * new_VioSSLConnectorFd(const char* key_file, const char* cert_file, @@ -185,7 +190,7 @@ new_VioSSLConnectorFd(const char* key_file, const char* ca_path, const char* cipher) { - int verify = SSL_VERIFY_PEER; + int verify = SSL_VERIFY_NONE; struct st_VioSSLConnectorFd* ptr; int result; DH *dh=NULL; @@ -264,7 +269,10 @@ ctor_failure: /************************ VioSSLAcceptorFd **********************************/ - +/* + TODO: + Add option --verify to mysqld to be able to change verification mode +*/ struct st_VioSSLAcceptorFd* new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, @@ -273,7 +281,6 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cipher) { int verify = (SSL_VERIFY_PEER | - SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE); struct st_VioSSLAcceptorFd* ptr; int result; From 8075aac74f93ba8f5ba61c2137e723124fb4599d Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Thu, 26 Jun 2003 21:30:53 +0200 Subject: [PATCH 078/237] bug with ranges and not_null_col=can_be_null_expr fixed --- mysql-test/r/range.result | 81 ++++++++++++++++++++++--------------- mysql-test/t/range.test | 84 ++++++++++++++++++++++++--------------- sql/opt_range.cc | 6 ++- 3 files changed, 107 insertions(+), 64 deletions(-) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index a1d258455dc..26d9d7869c6 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -5,7 +5,24 @@ type int(11) DEFAULT '0' NOT NULL, event_id int(11) DEFAULT '0' NOT NULL, PRIMARY KEY (event_date,type,event_id) ); -INSERT INTO t1 VALUES ('1999-07-10',100100,24),('1999-07-11',100100,25),('1999-07-13',100600,0),('1999-07-13',100600,4),('1999-07-13',100600,26),('1999-07-14',100600,10),('1999-07-15',100600,16),('1999-07-15',100800,45),('1999-07-15',101000,47),('1999-07-16',100800,46),('1999-07-20',100600,5),('1999-07-20',100600,27),('1999-07-21',100600,11),('1999-07-22',100600,17),('1999-07-23',100100,39),('1999-07-24',100100,39),('1999-07-24',100500,40),('1999-07-25',100100,39),('1999-07-27',100600,1),('1999-07-27',100600,6),('1999-07-27',100600,28),('1999-07-28',100600,12),('1999-07-29',100500,41),('1999-07-29',100600,18),('1999-07-30',100500,41),('1999-07-31',100500,41),('1999-08-01',100700,34),('1999-08-03',100600,7),('1999-08-03',100600,29),('1999-08-04',100600,13),('1999-08-05',100500,42),('1999-08-05',100600,19),('1999-08-06',100500,42),('1999-08-07',100500,42),('1999-08-08',100500,42),('1999-08-10',100600,2),('1999-08-10',100600,9),('1999-08-10',100600,30),('1999-08-11',100600,14),('1999-08-12',100600,20),('1999-08-17',100500,8),('1999-08-17',100600,31),('1999-08-18',100600,15),('1999-08-19',100600,22),('1999-08-24',100600,3),('1999-08-24',100600,32),('1999-08-27',100500,43),('1999-08-31',100600,33),('1999-09-17',100100,37),('1999-09-18',100100,37),('1999-09-19',100100,37),('2000-12-18',100700,38); +INSERT INTO t1 VALUES ('1999-07-10',100100,24), ('1999-07-11',100100,25), +('1999-07-13',100600,0), ('1999-07-13',100600,4), ('1999-07-13',100600,26), +('1999-07-14',100600,10), ('1999-07-15',100600,16), ('1999-07-15',100800,45), +('1999-07-15',101000,47), ('1999-07-16',100800,46), ('1999-07-20',100600,5), +('1999-07-20',100600,27), ('1999-07-21',100600,11), ('1999-07-22',100600,17), +('1999-07-23',100100,39), ('1999-07-24',100100,39), ('1999-07-24',100500,40), +('1999-07-25',100100,39), ('1999-07-27',100600,1), ('1999-07-27',100600,6), +('1999-07-27',100600,28), ('1999-07-28',100600,12), ('1999-07-29',100500,41), +('1999-07-29',100600,18), ('1999-07-30',100500,41), ('1999-07-31',100500,41), +('1999-08-01',100700,34), ('1999-08-03',100600,7), ('1999-08-03',100600,29), +('1999-08-04',100600,13), ('1999-08-05',100500,42), ('1999-08-05',100600,19), +('1999-08-06',100500,42), ('1999-08-07',100500,42), ('1999-08-08',100500,42), +('1999-08-10',100600,2), ('1999-08-10',100600,9), ('1999-08-10',100600,30), +('1999-08-11',100600,14), ('1999-08-12',100600,20), ('1999-08-17',100500,8), +('1999-08-17',100600,31), ('1999-08-18',100600,15), ('1999-08-19',100600,22), +('1999-08-24',100600,3), ('1999-08-24',100600,32), ('1999-08-27',100500,43), +('1999-08-31',100600,33), ('1999-09-17',100100,37), ('1999-09-18',100100,37), +('1999-09-19',100100,37), ('2000-12-18',100700,38); select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; event_date type event_id 1999-07-10 100100 24 @@ -35,35 +52,21 @@ CLOSED tinyint(4) DEFAULT '0' NOT NULL, ISS_DATE date DEFAULT '0000-00-00' NOT NULL, PRIMARY KEY (PAPER_ID,YEAR,ISSUE) ); -INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12'); -INSERT INTO t1 VALUES (1,1999,111,0,'1999-03-23'); -INSERT INTO t1 VALUES (1,1999,222,0,'1999-03-23'); -INSERT INTO t1 VALUES (3,1999,33,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,32,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,31,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,30,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,29,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,28,0,'1999-07-12'); -INSERT INTO t1 VALUES (1,1999,40,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,41,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,42,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,46,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,47,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,48,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,49,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,50,0,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,51,0,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,200,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,52,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,53,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,54,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,55,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,56,0,'1999-07-01'); -INSERT INTO t1 VALUES (1,1999,57,0,'1999-07-01'); -INSERT INTO t1 VALUES (1,1999,58,0,'1999-07-01'); -INSERT INTO t1 VALUES (1,1999,59,0,'1999-07-01'); -INSERT INTO t1 VALUES (1,1999,60,0,'1999-07-01'); -INSERT INTO t1 VALUES (3,1999,35,0,'1999-07-12'); +INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12'), (1,1999,111,0,'1999-03-23'), +(1,1999,222,0,'1999-03-23'), (3,1999,33,0,'1999-07-12'), +(3,1999,32,0,'1999-07-12'), (3,1999,31,0,'1999-07-12'), +(3,1999,30,0,'1999-07-12'), (3,1999,29,0,'1999-07-12'), +(3,1999,28,0,'1999-07-12'), (1,1999,40,1,'1999-05-01'), +(1,1999,41,1,'1999-05-01'), (1,1999,42,1,'1999-05-01'), +(1,1999,46,1,'1999-05-01'), (1,1999,47,1,'1999-05-01'), +(1,1999,48,1,'1999-05-01'), (1,1999,49,1,'1999-05-01'), +(1,1999,50,0,'1999-05-01'), (1,1999,51,0,'1999-05-01'), +(1,1999,200,0,'1999-06-28'), (1,1999,52,0,'1999-06-28'), +(1,1999,53,0,'1999-06-28'), (1,1999,54,0,'1999-06-28'), +(1,1999,55,0,'1999-06-28'), (1,1999,56,0,'1999-07-01'), +(1,1999,57,0,'1999-07-01'), (1,1999,58,0,'1999-07-01'), +(1,1999,59,0,'1999-07-01'), (1,1999,60,0,'1999-07-01'), +(3,1999,35,0,'1999-07-12'); select YEAR,ISSUE from t1 where PAPER_ID=3 and (YEAR>1999 or (YEAR=1999 and ISSUE>28)) order by YEAR,ISSUE; YEAR ISSUE 1999 29 @@ -88,7 +91,12 @@ PRIMARY KEY (id), KEY parent_id (parent_id), KEY level (level) ); -INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2); +INSERT INTO t1 VALUES (1,0,0), (3,1,1), (4,1,1), (8,2,2), (9,2,2), (17,3,2), +(22,4,2), (24,4,2), (28,5,2), (29,5,2), (30,5,2), (31,6,2), (32,6,2), (33,6,2), +(203,7,2), (202,7,2), (20,3,2), (157,0,0), (193,5,2), (40,7,2), (2,1,1), +(15,2,2), (6,1,1), (34,6,2), (35,6,2), (16,3,2), (7,1,1), (36,7,2), (18,3,2), +(26,5,2), (27,5,2), (183,4,2), (38,7,2), (25,5,2), (37,7,2), (21,4,2), +(19,3,2), (5,1,1), (179,5,2); SELECT * FROM t1 WHERE level = 1 AND parent_id = 1; id parent_id level 3 1 1 @@ -207,3 +215,14 @@ select count(*) from t1 where art = 'J'; count(*) 213 drop table t1; +create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2)); +insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"), +(3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"), +(6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"), +(9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"), +(12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"), +(15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"), +(18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa"); +select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1; +id1 idnull +drop table t1; diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 278807eeea4..bb0e696ea11 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -1,5 +1,5 @@ # -# Problem med range optimizer +# Problem with range optimizer # drop table if exists t1; @@ -10,7 +10,24 @@ CREATE TABLE t1 ( PRIMARY KEY (event_date,type,event_id) ); -INSERT INTO t1 VALUES ('1999-07-10',100100,24),('1999-07-11',100100,25),('1999-07-13',100600,0),('1999-07-13',100600,4),('1999-07-13',100600,26),('1999-07-14',100600,10),('1999-07-15',100600,16),('1999-07-15',100800,45),('1999-07-15',101000,47),('1999-07-16',100800,46),('1999-07-20',100600,5),('1999-07-20',100600,27),('1999-07-21',100600,11),('1999-07-22',100600,17),('1999-07-23',100100,39),('1999-07-24',100100,39),('1999-07-24',100500,40),('1999-07-25',100100,39),('1999-07-27',100600,1),('1999-07-27',100600,6),('1999-07-27',100600,28),('1999-07-28',100600,12),('1999-07-29',100500,41),('1999-07-29',100600,18),('1999-07-30',100500,41),('1999-07-31',100500,41),('1999-08-01',100700,34),('1999-08-03',100600,7),('1999-08-03',100600,29),('1999-08-04',100600,13),('1999-08-05',100500,42),('1999-08-05',100600,19),('1999-08-06',100500,42),('1999-08-07',100500,42),('1999-08-08',100500,42),('1999-08-10',100600,2),('1999-08-10',100600,9),('1999-08-10',100600,30),('1999-08-11',100600,14),('1999-08-12',100600,20),('1999-08-17',100500,8),('1999-08-17',100600,31),('1999-08-18',100600,15),('1999-08-19',100600,22),('1999-08-24',100600,3),('1999-08-24',100600,32),('1999-08-27',100500,43),('1999-08-31',100600,33),('1999-09-17',100100,37),('1999-09-18',100100,37),('1999-09-19',100100,37),('2000-12-18',100700,38); +INSERT INTO t1 VALUES ('1999-07-10',100100,24), ('1999-07-11',100100,25), +('1999-07-13',100600,0), ('1999-07-13',100600,4), ('1999-07-13',100600,26), +('1999-07-14',100600,10), ('1999-07-15',100600,16), ('1999-07-15',100800,45), +('1999-07-15',101000,47), ('1999-07-16',100800,46), ('1999-07-20',100600,5), +('1999-07-20',100600,27), ('1999-07-21',100600,11), ('1999-07-22',100600,17), +('1999-07-23',100100,39), ('1999-07-24',100100,39), ('1999-07-24',100500,40), +('1999-07-25',100100,39), ('1999-07-27',100600,1), ('1999-07-27',100600,6), +('1999-07-27',100600,28), ('1999-07-28',100600,12), ('1999-07-29',100500,41), +('1999-07-29',100600,18), ('1999-07-30',100500,41), ('1999-07-31',100500,41), +('1999-08-01',100700,34), ('1999-08-03',100600,7), ('1999-08-03',100600,29), +('1999-08-04',100600,13), ('1999-08-05',100500,42), ('1999-08-05',100600,19), +('1999-08-06',100500,42), ('1999-08-07',100500,42), ('1999-08-08',100500,42), +('1999-08-10',100600,2), ('1999-08-10',100600,9), ('1999-08-10',100600,30), +('1999-08-11',100600,14), ('1999-08-12',100600,20), ('1999-08-17',100500,8), +('1999-08-17',100600,31), ('1999-08-18',100600,15), ('1999-08-19',100600,22), +('1999-08-24',100600,3), ('1999-08-24',100600,32), ('1999-08-27',100500,43), +('1999-08-31',100600,33), ('1999-09-17',100100,37), ('1999-09-18',100100,37), +('1999-09-19',100100,37), ('2000-12-18',100700,38); select event_date,type,event_id from t1 WHERE event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; explain select event_date,type,event_id from t1 WHERE type = 100601 and event_date >= "1999-07-01" AND event_date < "1999-07-15" AND (type=100600 OR type=100100) ORDER BY event_date; @@ -25,35 +42,21 @@ CREATE TABLE t1 ( ISS_DATE date DEFAULT '0000-00-00' NOT NULL, PRIMARY KEY (PAPER_ID,YEAR,ISSUE) ); -INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12'); -INSERT INTO t1 VALUES (1,1999,111,0,'1999-03-23'); -INSERT INTO t1 VALUES (1,1999,222,0,'1999-03-23'); -INSERT INTO t1 VALUES (3,1999,33,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,32,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,31,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,30,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,29,0,'1999-07-12'); -INSERT INTO t1 VALUES (3,1999,28,0,'1999-07-12'); -INSERT INTO t1 VALUES (1,1999,40,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,41,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,42,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,46,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,47,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,48,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,49,1,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,50,0,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,51,0,'1999-05-01'); -INSERT INTO t1 VALUES (1,1999,200,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,52,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,53,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,54,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,55,0,'1999-06-28'); -INSERT INTO t1 VALUES (1,1999,56,0,'1999-07-01'); -INSERT INTO t1 VALUES (1,1999,57,0,'1999-07-01'); -INSERT INTO t1 VALUES (1,1999,58,0,'1999-07-01'); -INSERT INTO t1 VALUES (1,1999,59,0,'1999-07-01'); -INSERT INTO t1 VALUES (1,1999,60,0,'1999-07-01'); -INSERT INTO t1 VALUES (3,1999,35,0,'1999-07-12'); +INSERT INTO t1 VALUES (3,1999,34,0,'1999-07-12'), (1,1999,111,0,'1999-03-23'), + (1,1999,222,0,'1999-03-23'), (3,1999,33,0,'1999-07-12'), + (3,1999,32,0,'1999-07-12'), (3,1999,31,0,'1999-07-12'), + (3,1999,30,0,'1999-07-12'), (3,1999,29,0,'1999-07-12'), + (3,1999,28,0,'1999-07-12'), (1,1999,40,1,'1999-05-01'), + (1,1999,41,1,'1999-05-01'), (1,1999,42,1,'1999-05-01'), + (1,1999,46,1,'1999-05-01'), (1,1999,47,1,'1999-05-01'), + (1,1999,48,1,'1999-05-01'), (1,1999,49,1,'1999-05-01'), + (1,1999,50,0,'1999-05-01'), (1,1999,51,0,'1999-05-01'), + (1,1999,200,0,'1999-06-28'), (1,1999,52,0,'1999-06-28'), + (1,1999,53,0,'1999-06-28'), (1,1999,54,0,'1999-06-28'), + (1,1999,55,0,'1999-06-28'), (1,1999,56,0,'1999-07-01'), + (1,1999,57,0,'1999-07-01'), (1,1999,58,0,'1999-07-01'), + (1,1999,59,0,'1999-07-01'), (1,1999,60,0,'1999-07-01'), + (3,1999,35,0,'1999-07-12'); select YEAR,ISSUE from t1 where PAPER_ID=3 and (YEAR>1999 or (YEAR=1999 and ISSUE>28)) order by YEAR,ISSUE; check table t1; repair table t1; @@ -67,7 +70,12 @@ CREATE TABLE t1 ( KEY parent_id (parent_id), KEY level (level) ); -INSERT INTO t1 VALUES (1,0,0),(3,1,1),(4,1,1),(8,2,2),(9,2,2),(17,3,2),(22,4,2),(24,4,2),(28,5,2),(29,5,2),(30,5,2),(31,6,2),(32,6,2),(33,6,2),(203,7,2),(202,7,2),(20,3,2),(157,0,0),(193,5,2),(40,7,2),(2,1,1),(15,2,2),(6,1,1),(34,6,2),(35,6,2),(16,3,2),(7,1,1),(36,7,2),(18,3,2),(26,5,2),(27,5,2),(183,4,2),(38,7,2),(25,5,2),(37,7,2),(21,4,2),(19,3,2),(5,1,1),(179,5,2); +INSERT INTO t1 VALUES (1,0,0), (3,1,1), (4,1,1), (8,2,2), (9,2,2), (17,3,2), +(22,4,2), (24,4,2), (28,5,2), (29,5,2), (30,5,2), (31,6,2), (32,6,2), (33,6,2), +(203,7,2), (202,7,2), (20,3,2), (157,0,0), (193,5,2), (40,7,2), (2,1,1), +(15,2,2), (6,1,1), (34,6,2), (35,6,2), (16,3,2), (7,1,1), (36,7,2), (18,3,2), +(26,5,2), (27,5,2), (183,4,2), (38,7,2), (25,5,2), (37,7,2), (21,4,2), +(19,3,2), (5,1,1), (179,5,2); SELECT * FROM t1 WHERE level = 1 AND parent_id = 1; # The following select returned 0 rows in 3.23.8 SELECT * FROM t1 WHERE level = 1 AND parent_id = 1 order by id; @@ -163,3 +171,15 @@ select count(*) from t1 where art = 'j' or art = 'J'; select count(*) from t1 where art = 'j'; select count(*) from t1 where art = 'J'; drop table t1; + +create table t1 ( id1 int not null, id2 int not null, idnull int null, c char(20), primary key (id1,id2)); +insert into t1 values (0,1,NULL,"aaa"), (1,1,NULL,"aaa"), (2,1,NULL,"aaa"), + (3,1,NULL,"aaa"), (4,1,NULL,"aaa"), (5,1,NULL,"aaa"), + (6,1,NULL,"aaa"), (7,1,NULL,"aaa"), (8,1,NULL,"aaa"), + (9,1,NULL,"aaa"), (10,1,NULL,"aaa"), (11,1,NULL,"aaa"), + (12,1,NULL,"aaa"), (13,1,NULL,"aaa"), (14,1,NULL,"aaa"), + (15,1,NULL,"aaa"), (16,1,NULL,"aaa"), (17,1,NULL,"aaa"), + (18,1,NULL,"aaa"), (19,1,NULL,"aaa"), (20,1,NULL,"aaa"); +select a.id1, b.idnull from t1 as a, t1 as b where a.id2=1 and a.id1=1 and b.id1=a.idnull order by b.id2 desc limit 1; +drop table t1; + diff --git a/sql/opt_range.cc b/sql/opt_range.cc index cc45e18e54c..5704ce6e432 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2408,9 +2408,13 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref) if (!quick) return 0; + if (cp_buffer_from_ref(ref)) + return quick; /* empty range */ + QUICK_RANGE *range= new QUICK_RANGE(); - if (!range || cp_buffer_from_ref(ref)) + if (!range) goto err; + range->min_key=range->max_key=(char*) ref->key_buff; range->min_length=range->max_length=ref->key_length; range->flag= ((ref->key_length == key_info->key_length && From 34919a03c4d0d17e6bb5f11fab53366ee04ea7f9 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Fri, 27 Jun 2003 03:04:54 +0300 Subject: [PATCH 079/237] Added thread variable max_seeks_for_key Change optimizer to prefer key lookups before table scan Change table scans to be done after tables with constrains on scanned table --- mysql-test/r/distinct.result | 12 +++++----- mysql-test/r/group_by.result | 4 ++-- mysql-test/r/heap.result | 2 +- mysql-test/r/join.result | 4 +--- mysql-test/r/key_diff.result | 2 +- mysql-test/r/myisam.result | 10 ++++---- mysql-test/r/order_by.result | 6 ++--- mysql-test/r/select_safe.result | 23 ++++++++++++++---- mysql-test/t/distinct.test | 2 +- mysql-test/t/join.test | 5 +--- mysql-test/t/select_safe.test | 15 ++++++++++-- sql/handler.h | 37 ++++++++++++++--------------- sql/item_cmpfunc.cc | 4 ++-- sql/mysqld.cc | 7 +++++- sql/set_var.cc | 4 ++++ sql/sql_class.h | 1 + sql/sql_select.cc | 41 +++++++++++++++++++++++---------- 17 files changed, 114 insertions(+), 65 deletions(-) diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 5f4f7cced1e..53a20eeea0b 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -161,7 +161,7 @@ SELECT DISTINCT UserId FROM t1 WHERE UserId=22; UserId drop table t1; CREATE TABLE t1 (a int(10) unsigned not null primary key,b int(10) unsigned); -INSERT INTO t1 VALUES (1,1),(2,1); +INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1); CREATE TABLE t2 (a int(10) unsigned not null, key (A)); INSERT INTO t2 VALUES (1),(2); CREATE TABLE t3 (a int(10) unsigned, key(A), b text); @@ -189,7 +189,7 @@ insert into t4 select * from t3; insert into t3 select * from t4; explain select distinct t1.a from t1,t3 where t1.a=t3.a; table type possible_keys key key_len ref rows Extra -t1 index PRIMARY PRIMARY 4 NULL 2 Using index; Using temporary +t1 index PRIMARY PRIMARY 4 NULL 4 Using index; Using temporary t3 ref a a 5 t1.a 10 Using where; Using index; Distinct select distinct t1.a from t1,t3 where t1.a=t3.a; a @@ -200,16 +200,16 @@ select distinct 1 from t1,t3 where t1.a=t3.a; 1 explain SELECT distinct t1.a from t1; table type possible_keys key key_len ref rows Extra -t1 index NULL PRIMARY 4 NULL 2 Using index +t1 index NULL PRIMARY 4 NULL 4 Using index explain SELECT distinct t1.a from t1 order by a desc; table type possible_keys key key_len ref rows Extra -t1 index NULL PRIMARY 4 NULL 2 Using index +t1 index NULL PRIMARY 4 NULL 4 Using index explain SELECT t1.a from t1 group by a order by a desc; table type possible_keys key key_len ref rows Extra -t1 index NULL PRIMARY 4 NULL 2 Using index +t1 index NULL PRIMARY 4 NULL 4 Using index explain SELECT distinct t1.a from t1 order by a desc limit 1; table type possible_keys key key_len ref rows Extra -t1 index NULL PRIMARY 4 NULL 2 Using index +t1 index NULL PRIMARY 4 NULL 4 Using index explain SELECT distinct a from t3 order by a desc limit 2; table type possible_keys key key_len ref rows Extra t3 index NULL a 5 NULL 204 Using index diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index 94e1ce59585..67e6bec09f6 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -534,11 +534,11 @@ a b explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b; table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort -t2 ALL a NULL NULL NULL 4 Using where +t2 ALL a NULL NULL NULL 3 Using where explain select t1.a,t2.b from t1,t2 where t1.a=t2.a group by t1.a,t2.b ORDER BY NULL; table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 6 Using temporary -t2 ALL a NULL NULL NULL 4 Using where +t2 ALL a NULL NULL NULL 3 Using where drop table t1,t2; create table t1 (a int, b int); insert into t1 values (1, 4),(10, 40),(1, 4),(10, 43),(1, 4),(10, 41),(1, 4),(10, 43),(1, 4); diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index d8905085e34..a04ddf3f302 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -166,7 +166,7 @@ alter table t1 add column new_col char(1) not null, add key (btn,new_col), drop update t1 set new_col=btn; explain select * from t1 where btn="a"; table type possible_keys key key_len ref rows Extra -t1 ALL btn NULL NULL NULL 14 Using where +t1 ALL btn NULL NULL NULL 11 Using where explain select * from t1 where btn="a" and new_col="a"; table type possible_keys key key_len ref rows Extra t1 ref btn btn 11 const,const 10 Using where diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result index e063b5c3e02..039b6e1cba3 100644 --- a/mysql-test/r/join.result +++ b/mysql-test/r/join.result @@ -104,9 +104,7 @@ KEY category (category,county,state) INSERT INTO t2 VALUES (3,2,11,12,5400,7800); INSERT INTO t2 VALUES (4,2,25,12,6500,11200); INSERT INTO t2 VALUES (5,1,37,6,10000,12000); -select a.id, b.category as catid, b.state as stateid, b.county as -countyid from t1 a, t2 b where (a.token = -'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id); +select a.id, b.category as catid, b.state as stateid, b.county as countyid from t1 a, t2 b ignore index (primary) where (a.token ='a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id); id catid stateid countyid 27 2 12 11 28 2 12 11 diff --git a/mysql-test/r/key_diff.result b/mysql-test/r/key_diff.result index 4eaccc696f9..2d4bc19474f 100644 --- a/mysql-test/r/key_diff.result +++ b/mysql-test/r/key_diff.result @@ -36,7 +36,7 @@ a a a a explain select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B; table type possible_keys key key_len ref rows Extra t1 ALL a NULL NULL NULL 5 -t2 ALL b NULL NULL NULL 5 Using where +t2 ALL b NULL NULL NULL 4 Using where select t1.*,t2.* from t1,t1 as t2 where t1.A=t2.B order by binary t1.a,t2.a; a b a b A B a a diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 9a653aff99e..c4368384bf8 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -335,12 +335,12 @@ t1 1 c_2 1 c A 5 NULL NULL YES BTREE t1 1 c_2 2 a A 5 NULL NULL BTREE explain select * from t1,t2 where t1.a=t2.a; table type possible_keys key key_len ref rows Extra -t1 ALL a NULL NULL NULL 5 -t2 ALL a NULL NULL NULL 2 Using where +t2 ALL a NULL NULL NULL 2 +t1 ALL a NULL NULL NULL 4 Using where explain select * from t1,t2 force index(a) where t1.a=t2.a; table type possible_keys key key_len ref rows Extra t2 ALL a NULL NULL NULL 2 -t1 ALL a NULL NULL NULL 5 Using where +t1 ALL a NULL NULL NULL 4 Using where explain select * from t1 force index(a),t2 force index(a) where t1.a=t2.a; table type possible_keys key key_len ref rows Extra t2 ALL a NULL NULL NULL 2 @@ -351,8 +351,8 @@ t2 ALL b NULL NULL NULL 2 t1 ref b b 5 t2.b 1 Using where explain select * from t1,t2 force index(c) where t1.a=t2.a; table type possible_keys key key_len ref rows Extra -t1 ALL a NULL NULL NULL 5 -t2 ALL NULL NULL NULL NULL 2 Using where +t2 ALL NULL NULL NULL NULL 2 +t1 ALL a NULL NULL NULL 4 Using where explain select * from t1 where a=0 or a=2; table type possible_keys key key_len ref rows Extra t1 ALL a NULL NULL NULL 5 Using where diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index ff2dd93311c..64fac8af872 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -307,17 +307,17 @@ table type possible_keys key key_len ref rows Extra t1 range a a 9 NULL 8 Using where; Using index explain select * from t1 where a = 2 and b >0 order by a desc,b desc; table type possible_keys key key_len ref rows Extra -t1 range a a 9 NULL 5 Using where; Using index +t1 range a a 9 NULL 4 Using where; Using index explain select * from t1 where a = 2 and b is null order by a desc,b desc; table type possible_keys key key_len ref rows Extra t1 ref a a 9 const,const 1 Using where; Using index; Using filesort explain select * from t1 where a = 2 and (b is null or b > 0) order by a desc,b desc; table type possible_keys key key_len ref rows Extra -t1 range a a 9 NULL 6 Using where; Using index +t1 range a a 9 NULL 5 Using where; Using index explain select * from t1 where a = 2 and b > 0 order by a desc,b desc; table type possible_keys key key_len ref rows Extra -t1 range a a 9 NULL 5 Using where; Using index +t1 range a a 9 NULL 4 Using where; Using index explain select * from t1 where a = 2 and b < 2 order by a desc,b desc; table type possible_keys key key_len ref rows Extra t1 range a a 9 NULL 2 Using where; Using index diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result index 3303f19d9c7..830390ebe3c 100644 --- a/mysql-test/r/select_safe.result +++ b/mysql-test/r/select_safe.result @@ -1,6 +1,6 @@ drop table if exists t1; SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=4, SQL_MAX_JOIN_SIZE=9; -create table t1 (a int auto_increment primary key, b char(20)); +create table t1 (a int auto_increment primary key, b char(20), key(b)); insert into t1 values(1,"test"); SELECT SQL_BUFFER_RESULT * from t1; a b @@ -13,7 +13,7 @@ a b 1 test 2 test2 update t1 set b="a" where a=1; -select 1 from t1,t1 as t2,t1 as t3,t1 as t4; +select 1 from t1,t1 as t2,t1 as t3; 1 1 1 @@ -22,11 +22,9 @@ select 1 from t1,t1 as t2,t1 as t3,t1 as t4; update t1 set b="a"; You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column update t1 set b="a" where b="test"; -You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column delete from t1; You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column delete from t1 where b="test"; -You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column delete from t1 where a+0=1; You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5; @@ -59,5 +57,22 @@ a b 2 test2 4 a 5 a +SELECT @@MAX_SEEKS_FOR_KEY; +@@max_seeks_for_key +4294967295 +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"); +explain select * from t1,t1 as t2 where t1.b=t2.b; +table type possible_keys key key_len ref rows Extra +t1 ALL b NULL NULL NULL 21 +t2 ALL b NULL NULL NULL 16 Using where +set MAX_SEEKS_FOR_KEY=1; +explain select * from t1,t1 as t2 where t1.b=t2.b; +table type possible_keys key key_len ref rows Extra +t1 ALL b NULL NULL NULL 21 +t2 ref b b 21 t1.b 6 Using where +SET MAX_SEEKS_FOR_KEY=DEFAULT; drop table t1; SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, SQL_MAX_JOIN_SIZE=DEFAULT; diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 7f75b6b1687..ecce2409571 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -60,7 +60,7 @@ drop table t1; # CREATE TABLE t1 (a int(10) unsigned not null primary key,b int(10) unsigned); -INSERT INTO t1 VALUES (1,1),(2,1); +INSERT INTO t1 VALUES (1,1),(2,1),(3,1),(4,1); CREATE TABLE t2 (a int(10) unsigned not null, key (A)); INSERT INTO t2 VALUES (1),(2); CREATE TABLE t3 (a int(10) unsigned, key(A), b text); diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test index 08cc5731723..19e04d2aa7e 100644 --- a/mysql-test/t/join.test +++ b/mysql-test/t/join.test @@ -98,10 +98,7 @@ CREATE TABLE t2 ( INSERT INTO t2 VALUES (3,2,11,12,5400,7800); INSERT INTO t2 VALUES (4,2,25,12,6500,11200); INSERT INTO t2 VALUES (5,1,37,6,10000,12000); - -select a.id, b.category as catid, b.state as stateid, b.county as -countyid from t1 a, t2 b where (a.token = -'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id); +select a.id, b.category as catid, b.state as stateid, b.county as countyid from t1 a, t2 b ignore index (primary) where (a.token ='a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id); select a.id, b.category as catid, b.state as stateid, b.county as countyid from t1 a, t2 b where (a.token = 'a71250b7ed780f6ef3185bfffe027983') and (a.count = b.id) order by a.id; diff --git a/mysql-test/t/select_safe.test b/mysql-test/t/select_safe.test index a085cfee29d..049a35aa355 100644 --- a/mysql-test/t/select_safe.test +++ b/mysql-test/t/select_safe.test @@ -4,7 +4,7 @@ drop table if exists t1; SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=4, SQL_MAX_JOIN_SIZE=9; -create table t1 (a int auto_increment primary key, b char(20)); +create table t1 (a int auto_increment primary key, b char(20), key(b)); insert into t1 values(1,"test"); SELECT SQL_BUFFER_RESULT * from t1; update t1 set b="a" where a=1; @@ -12,7 +12,7 @@ delete from t1 where a=1; insert into t1 values(1,"test"),(2,"test2"); SELECT SQL_BUFFER_RESULT * from t1; update t1 set b="a" where a=1; -select 1 from t1,t1 as t2,t1 as t3,t1 as t4; +select 1 from t1,t1 as t2,t1 as t3; # The following should give errors: --error 1175 @@ -49,6 +49,17 @@ SELECT * from t1; SET MAX_JOIN_SIZE=DEFAULT; SELECT * from t1; +# +# Test MAX_SEEKS_FOR_KEY +# +SELECT @@MAX_SEEKS_FOR_KEY; +analyze table t1; +insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"); +explain select * from t1,t1 as t2 where t1.b=t2.b; +set MAX_SEEKS_FOR_KEY=1; +explain select * from t1,t1 as t2 where t1.b=t2.b; +SET MAX_SEEKS_FOR_KEY=DEFAULT; + drop table t1; SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, SQL_MAX_JOIN_SIZE=DEFAULT; diff --git a/sql/handler.h b/sql/handler.h index 56f63d1d521..dfcfa44fbcd 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -184,40 +184,41 @@ class handler :public Sql_alloc { protected: struct st_table *table; /* The table definition */ - uint active_index; public: byte *ref; /* Pointer to current row */ byte *dupp_ref; /* Pointer to dupp row */ - uint ref_length; /* Length of ref (1-8 or the clustered - key length) */ - uint block_size; /* index block size */ - ha_rows records; /* Records i datafilen */ - ha_rows deleted; /* Deleted records */ ulonglong data_file_length; /* Length off data file */ ulonglong max_data_file_length; /* Length off data file */ ulonglong index_file_length; ulonglong max_index_file_length; ulonglong delete_length; /* Free bytes */ ulonglong auto_increment_value; - uint raid_type,raid_chunks; + ha_rows records; /* Records in table */ + ha_rows deleted; /* Deleted records */ ulong raid_chunksize; - uint errkey; /* Last dup key */ - uint sortkey, key_used_on_scan; + ulong mean_rec_length; /* physical reclength */ time_t create_time; /* When table was created */ time_t check_time; time_t update_time; - ulong mean_rec_length; /* physical reclength */ + uint errkey; /* Last dup key */ + uint sortkey, key_used_on_scan; + uint active_index; + /* Length of ref (1-8 or the clustered key length) */ + uint ref_length; + uint block_size; /* index block size */ + uint raid_type,raid_chunks; FT_INFO *ft_handler; bool auto_increment_column_changed; - handler(TABLE *table_arg) : table(table_arg),active_index(MAX_REF_PARTS), - ref(0),ref_length(sizeof(my_off_t)), block_size(0),records(0),deleted(0), - data_file_length(0), max_data_file_length(0), index_file_length(0), - delete_length(0), auto_increment_value(0), raid_type(0), - key_used_on_scan(MAX_KEY), - create_time(0), check_time(0), update_time(0), mean_rec_length(0), - ft_handler(0) + handler(TABLE *table_arg) :table(table_arg), + ref(0), data_file_length(0), max_data_file_length(0), index_file_length(0), + delete_length(0), auto_increment_value(0), + records(0), deleted(0), mean_rec_length(0), + create_time(0), check_time(0), update_time(0), + key_used_on_scan(MAX_KEY), active_index(MAX_REF_PARTS), + ref_length(sizeof(my_off_t)), block_size(0), + raid_type(0), ft_handler(0) {} virtual ~handler(void) {} int ha_open(const char *name, int mode, int test_if_locked); @@ -227,7 +228,7 @@ public: uint get_dup_key(int error); void change_table_ptr(TABLE *table_arg) { table=table_arg; } virtual double scan_time() - { return ulonglong2double(data_file_length) / IO_SIZE + 1; } + { return ulonglong2double(data_file_length) / IO_SIZE + 2; } virtual double read_time(uint index, uint ranges, ha_rows rows) { return rows2double(ranges+rows); } virtual bool fast_key_read() { return 0;} diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 770fe3c0232..78a63d84c61 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1175,8 +1175,8 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) List_iterator li(list); Item *item; char buff[sizeof(char*)]; // Max local vars in function - used_tables_cache=0; - const_item_cache=0; + not_null_tables_cache= used_tables_cache= 0; + const_item_cache= 0; /* and_table_cache is the value that Item_cond_or() returns for not_null_tables() diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5613f1eeb07..f27ba435729 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3154,7 +3154,7 @@ enum options { OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE, OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS, OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE, - OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH, + OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH, OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, @@ -3832,6 +3832,11 @@ replicating a LOAD DATA INFILE command", (gptr*) &global_system_variables.max_join_size, (gptr*) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, + { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY, + "Limit assumed max number of seeks when looking up rows based on a key", + (gptr*) &global_system_variables.max_seeks_for_key, + (gptr*) &max_system_variables.max_seeks_for_key, 0, GET_ULONG, + REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0 }, {"max_sort_length", OPT_MAX_SORT_LENGTH, "The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored).", (gptr*) &global_system_variables.max_sort_length, diff --git a/sql/set_var.cc b/sql/set_var.cc index 32603ec51d9..3edcdbc1f7f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -154,6 +154,8 @@ sys_var_thd_ulong sys_max_heap_table_size("max_heap_table_size", sys_var_thd_ha_rows sys_max_join_size("max_join_size", &SV::max_join_size, fix_max_join_size); +sys_var_thd_ulong sys_max_seeks_for_key("max_seeks_for_key", + &SV::max_seeks_for_key); #ifndef TO_BE_DELETED /* Alias for max_join_size */ sys_var_thd_ha_rows sys_sql_max_join_size("sql_max_join_size", &SV::max_join_size, @@ -348,6 +350,7 @@ sys_var *sys_variables[]= &sys_max_delayed_threads, &sys_max_heap_table_size, &sys_max_join_size, + &sys_max_seeks_for_key, &sys_max_sort_length, &sys_max_tmp_tables, &sys_max_user_connections, @@ -492,6 +495,7 @@ struct show_var_st init_vars[]= { {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS}, {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS}, {sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS}, + {sys_max_seeks_for_key.name, (char*) &sys_max_seeks_for_key, SHOW_SYS}, {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS}, {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS}, {sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 3246f77c77a..d1b2ef82ccb 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -310,6 +310,7 @@ struct system_variables ulong tx_isolation; ulong table_type; ulong default_week_format; + ulong max_seeks_for_key; my_bool log_warnings; my_bool low_priority_updates; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 67bec77e245..f4c7a2ab031 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1271,14 +1271,14 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, /* Set a max range of how many seeks we can expect when using keys - This was (s->read_time*5), but this was too low with small rows + This is can't be to high as otherwise we are likely to use + table scan. */ - s->worst_seeks= (double) s->found_records / 5; + s->worst_seeks= min((double) s->found_records / 10, + (double) s->read_time*3); if (s->worst_seeks < 2.0) // Fix for small tables s->worst_seeks=2.0; - /* if (s->type == JT_EQ_REF) - continue; */ if (s->const_keys) { ha_rows records; @@ -1884,6 +1884,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, best=best_time=records=DBL_MAX; KEYUSE *best_key=0; uint best_max_key_part=0; + my_bool found_constrain= 0; if (s->keyuse) { /* Use key if possible */ @@ -1964,6 +1965,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, } else { + found_constrain= 1; /* Check if we found full key */ @@ -2000,16 +2002,18 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, records=2.0; // Can't be as good as a unique } } + /* Limit the number of matched rows */ + tmp= records; + set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key); if (table->used_keys & ((key_map) 1 << key)) { /* we can use only index tree */ uint keys_per_block= table->file->block_size/2/ (keyinfo->key_length+table->file->ref_length)+1; - tmp=(record_count*(records+keys_per_block-1)/ - keys_per_block); + tmp=record_count*(tmp+keys_per_block-1)/keys_per_block; } else - tmp=record_count*min(records,s->worst_seeks); + tmp=record_count*min(tmp,s->worst_seeks); } } else @@ -2039,7 +2043,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, { /* Assume that the first key part matches 1% of the file - and that the hole key matches 10 (dupplicates) or 1 + and that the hole key matches 10 (duplicates) or 1 (unique) records. Assume also that more key matches proportionally more records @@ -2071,6 +2075,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, records=(ulong) tmp; } } + /* Limit the number of matched rows */ + set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key); if (table->used_keys & ((key_map) 1 << key)) { /* we can use only index tree */ @@ -2113,20 +2119,31 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, s->table->used_keys && best_key) && !(s->table->force_index && best_key)) { // Check full join + ha_rows rnd_records= s->found_records; if (s->on_expr) { - tmp=rows2double(s->found_records); // Can't use read cache + tmp=rows2double(rnd_records); // Can't use read cache } else { tmp=(double) s->read_time; - /* Calculate time to read through cache */ + /* Calculate time to read previous rows through cache */ tmp*=(1.0+floor((double) cache_record_length(join,idx)* record_count / (double) thd->variables.join_buff_size)); } + + /* + If there is a restriction on the table, assume that 25% of the + rows can be skipped on next part. + This is to force tables that this table depends on before this + table + */ + if (found_constrain) + rnd_records-= rnd_records/4; + if (best == DBL_MAX || - (tmp + record_count/(double) TIME_FOR_COMPARE*s->found_records < + (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records < best + record_count/(double) TIME_FOR_COMPARE*records)) { /* @@ -2134,7 +2151,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, will ensure that this will be used */ best=tmp; - records= rows2double(s->found_records); + records= rows2double(rnd_records); best_key=0; } } From 863c563481c2275000dd327fedefde489db007a7 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Fri, 27 Jun 2003 06:40:24 +0300 Subject: [PATCH 080/237] Fixed testcase after last changes --- mysql-test/r/select_safe.result | 13 ++++++++----- mysql-test/t/select_safe.test | 7 ++++--- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result index 830390ebe3c..ca5c03bdb50 100644 --- a/mysql-test/r/select_safe.result +++ b/mysql-test/r/select_safe.result @@ -1,6 +1,6 @@ drop table if exists t1; SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=4, SQL_MAX_JOIN_SIZE=9; -create table t1 (a int auto_increment primary key, b char(20), key(b)); +create table t1 (a int auto_increment primary key, b char(20)); insert into t1 values(1,"test"); SELECT SQL_BUFFER_RESULT * from t1; a b @@ -22,9 +22,11 @@ select 1 from t1,t1 as t2,t1 as t3; update t1 set b="a"; You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column update t1 set b="a" where b="test"; +You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column delete from t1; You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column delete from t1 where b="test"; +You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column delete from t1 where a+0=1; You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column select 1 from t1,t1 as t2,t1 as t3,t1 as t4,t1 as t5; @@ -33,18 +35,19 @@ update t1 set b="a" limit 1; update t1 set b="a" where b="b" limit 2; delete from t1 where b="test" limit 1; delete from t1 where a+0=1 limit 2; +alter table t1 add key b (b); SET MAX_JOIN_SIZE=2; SELECT @@MAX_JOIN_SIZE, @@SQL_BIG_SELECTS; @@max_join_size @@sql_big_selects 2 0 insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"); -SELECT * from t1; +SELECT * from t1 order by a; The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET SQL_BIG_SELECTS=1 or SET SQL_MAX_JOIN_SIZE=# if the SELECT is ok SET SQL_BIG_SELECTS=1; -SELECT * from t1; +SELECT * from t1 order by a; a b -3 a 2 test2 +3 a 4 a 5 a SET MAX_JOIN_SIZE=2; @@ -53,8 +56,8 @@ The SELECT would examine more rows than MAX_JOIN_SIZE. Check your WHERE and use SET MAX_JOIN_SIZE=DEFAULT; SELECT * from t1; a b -3 a 2 test2 +3 a 4 a 5 a SELECT @@MAX_SEEKS_FOR_KEY; diff --git a/mysql-test/t/select_safe.test b/mysql-test/t/select_safe.test index 049a35aa355..206f911d028 100644 --- a/mysql-test/t/select_safe.test +++ b/mysql-test/t/select_safe.test @@ -4,7 +4,7 @@ drop table if exists t1; SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=4, SQL_MAX_JOIN_SIZE=9; -create table t1 (a int auto_increment primary key, b char(20), key(b)); +create table t1 (a int auto_increment primary key, b char(20)); insert into t1 values(1,"test"); SELECT SQL_BUFFER_RESULT * from t1; update t1 set b="a" where a=1; @@ -36,13 +36,14 @@ delete from t1 where a+0=1 limit 2; # Test SQL_BIG_SELECTS +alter table t1 add key b (b); SET MAX_JOIN_SIZE=2; SELECT @@MAX_JOIN_SIZE, @@SQL_BIG_SELECTS; insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"); --error 1104 -SELECT * from t1; +SELECT * from t1 order by a; SET SQL_BIG_SELECTS=1; -SELECT * from t1; +SELECT * from t1 order by a; SET MAX_JOIN_SIZE=2; --error 1104 SELECT * from t1; From 81a84424ee250b77ed8981e301bca64ec1c35f7e Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Sun, 29 Jun 2003 12:58:43 +0300 Subject: [PATCH 081/237] SET CHARACTER SET DEFAULT didn't work (Bug #462) --- BUILD/compile-pentium-debug-max | 2 +- mysql-test/r/convert.result | 17 +++++++++++++++++ mysql-test/t/convert.test | 11 +++++++++++ sql/set_var.cc | 5 +++++ sql/set_var.h | 1 + 5 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/convert.result create mode 100644 mysql-test/t/convert.test diff --git a/BUILD/compile-pentium-debug-max b/BUILD/compile-pentium-debug-max index f71b849384f..1684686ce8c 100755 --- a/BUILD/compile-pentium-debug-max +++ b/BUILD/compile-pentium-debug-max @@ -3,7 +3,7 @@ path=`dirname $0` . "$path/SETUP.sh" -extra_flags="$pentium_cflags $debug_cflags -DBIG_TABLES" +extra_flags="$pentium_cflags $debug_cflags" c_warnings="$c_warnings $debug_extra_warnings" cxx_warnings="$cxx_warnings $debug_extra_warnings" extra_configs="$pentium_configs $debug_configs" diff --git a/mysql-test/r/convert.result b/mysql-test/r/convert.result new file mode 100644 index 00000000000..f8dad8c69ba --- /dev/null +++ b/mysql-test/r/convert.result @@ -0,0 +1,17 @@ +select @@convert_character_set; +@@convert_character_set + +select @@global.convert_character_set; +@@global.convert_character_set + +show variables like "%convert_character_set%"; +Variable_name Value +convert_character_set +SET CHARACTER SET cp1251_koi8; +select @@convert_character_set; +@@convert_character_set +cp1251_koi8 +SET CHARACTER SET DEFAULT; +select @@convert_character_set; +@@convert_character_set + diff --git a/mysql-test/t/convert.test b/mysql-test/t/convert.test new file mode 100644 index 00000000000..f26ef3a8c72 --- /dev/null +++ b/mysql-test/t/convert.test @@ -0,0 +1,11 @@ +# Test of character set conversions + +# Test that SET DEFAULT works + +select @@convert_character_set; +select @@global.convert_character_set; +show variables like "%convert_character_set%"; +SET CHARACTER SET cp1251_koi8; +select @@convert_character_set; +SET CHARACTER SET DEFAULT; +select @@convert_character_set; diff --git a/sql/set_var.cc b/sql/set_var.cc index 3edcdbc1f7f..b66c410c6d5 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1083,6 +1083,11 @@ byte *sys_var_thd_conv_charset::value_ptr(THD *thd, enum_var_type type) } +void sys_var_thd_conv_charset::set_default(THD *thd, enum_var_type type) +{ + thd->variables.convert_set= global_system_variables.convert_set; +} + bool sys_var_timestamp::update(THD *thd, set_var *var) { diff --git a/sql/set_var.h b/sql/set_var.h index f33f53c5acc..e22c55276a7 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -412,6 +412,7 @@ public: return type != STRING_RESULT; /* Only accept strings */ } bool check_default(enum_var_type type) { return 0; } + void set_default(THD *thd, enum_var_type type); }; From 730776c4526fcba5264d6513c9cc019d5a265781 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Sun, 29 Jun 2003 21:15:51 +0300 Subject: [PATCH 082/237] Fixed 'Unknown error' when doing ORDER BY on reference table which was used with NULL value on NOT NULL column. (Bug #479) --- mysql-test/r/order_by.result | 4 ++++ mysql-test/t/order_by.test | 23 +++++++++++++++++++++++ sql/sql_select.cc | 14 +++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 1a292b1203c..d45ae6b6dec 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -142,3 +142,7 @@ t3 eq_ref PRIMARY PRIMARY 2 t1.gid 1 where used table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 6 Using temporary; Using filesort t3 eq_ref PRIMARY PRIMARY 2 t1.skr 1 where used +t2_id str +112633 t2 112633 +112634 t2 112634 +t2_id str diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 16094206745..d6be4c1c45c 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -247,3 +247,26 @@ EXPLAIN SELECT t1.gid, t2.sid, t3.uid from t2, t1, t3 where t2.gid = t1.gid and EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.gid = t3.uid order by t3.skr,t1.gid; EXPLAIN SELECT t1.gid, t3.uid from t1, t3 where t1.skr = t3.uid order by t1.gid,t3.skr; drop table t1,t2,t3; + +# +# Problem with lookup on NULL (Bug 479) +# + +CREATE TABLE t1 ( + t1_id int(10) unsigned NOT NULL default '0', + ref_id int(10) unsigned default NULL, + PRIMARY KEY (t1_id) +) TYPE=MyISAM; +INSERT INTO t1 VALUES (2401,14590),(2425,NULL); +CREATE TABLE t2 ( + t2_id int(10) unsigned NOT NULL default '0', + ref_id int(10) unsigned NOT NULL default '0', + str varchar(20) default NULL, + PRIMARY KEY (t2_id), + KEY ref_id (ref_id) +) TYPE=MyISAM; +INSERT INTO t2 VALUES (112633,14590,'t2 112633'),(112634,14590,'t2 112634'),(113166,14641,'t2 113166'),(113167,14641,'t2 113167'),(113168,14641,'t2 113168'),(113169,14641,'t2 113169'),(113170,14641,'t2 113170'),(113171,14641,'t2 113171'),(113172,14641,'t2 113172'),(113173,14641,'t2 113173'),(113174,14641,'t2 113174'),(113175,14641,'t2 113175'),(113436,14674,'t2 113436'),(113437,14674,'t2 113437'),(113486,14689,'t2 113486'),(113487,14689,'t2 113487'),(113488,14689,'t2 113488'),(113489,14689,'t2 113489'),(113504,14795,'t2 113504'),(115396,15024,'t2 115396'),(115397,15024,'t2 115397'); +SELECT t2_id, str FROM t1, t2 WHERE t1_id = 2401 AND t1.ref_id = t2.ref_id ORDER BY str, t2_id; +# This one gave an error +SELECT t2_id, str FROM t1, t2 WHERE t1_id = 2425 AND t1.ref_id = t2.ref_id ORDER BY str, t2_id; +DROP TABLE t1,t2; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index cafafee243e..b9e9c0a14fa 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5326,11 +5326,23 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) can use. */ if (!(select->quick=get_ft_or_quick_select_for_ref(table, tab))) - goto err; + { + if (current_thd->fatal_error) + goto err; // End of memory + /* + Impossible range (for example lookup on NULL on not null field) + Create empty result set + */ + if (!(table->record_pointers= my_malloc(1, MYF(MY_WME)))) + goto err; + table->found_records= 0; + goto end; + } } } table->found_records=filesort(&table,sortorder,length, select, 0L, select_limit, &examined_rows); +end: delete select; // filesort did select tab->select=0; tab->select_cond=0; From f2e0db481162cd1f6fe73a33bb6abcf311590cd7 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Mon, 30 Jun 2003 15:00:28 +0200 Subject: [PATCH 083/237] - make sure to compile with the correct --localstatedir and --libexedir paths for the binary distributions (this will hopefully resolve the "file /usr/local/mysql/libexec/mysqld doesn't exist" error that many people are facing) --- Build-tools/Do-compile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Build-tools/Do-compile b/Build-tools/Do-compile index b83eadcac63..45037c2f3f0 100755 --- a/Build-tools/Do-compile +++ b/Build-tools/Do-compile @@ -248,7 +248,8 @@ if ($opt_stage <= 1) $opt_config_options.= $opt_with_other_libc; } - check_system("$opt_config_env ./configure --prefix=/usr/local/mysql --with-comment=\"Official MySQL$opt_version_suffix binary\" --with-extra-charsets=complex --with-server-suffix=\"$opt_version_suffix\" --enable-thread-safe-client --enable-local-infile $opt_config_options","Thank you for choosing MySQL"); + $prefix="/usr/local/mysql"; + check_system("$opt_config_env ./configure --prefix=$prefix --localstatedir=$prefix/data --libexecdir=$prefix/bin --with-comment=\"Official MySQL$opt_version_suffix binary\" --with-extra-charsets=complex --with-server-suffix=\"$opt_version_suffix\" --enable-thread-safe-client --enable-local-infile $opt_config_options","Thank you for choosing MySQL"); if (-d "$pwd/$host/include-mysql") { safe_system("cp -r $pwd/$host/include-mysql/* $pwd/$host/$ver/include"); From d71b51323b8734955a1cca7c7f328dfecad836dd Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 30 Jun 2003 17:00:11 +0200 Subject: [PATCH 084/237] REPAIR/OPTIMIZE/CHECK/RESTORE/etc commands close relevant open HANDLERs --- sql/sql_table.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f3620b860a7..5a53ba30631 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1198,6 +1198,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, if (send_fields(thd, field_list, 1)) DBUG_RETURN(-1); + mysql_ha_closeall(thd, tables); for (table = tables; table; table = table->next) { char table_name[NAME_LEN*2+2]; From 9c89341fd6538b709af134f20156f6aa8d3e81d0 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 30 Jun 2003 22:24:03 +0200 Subject: [PATCH 085/237] new syntax: CREATE TABLE ...(SELECT ...) UNION ... INSERT ... (SELECT ...) UNION ... --- sql/sql_yacc.yy | 48 ++++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0ff09a52a9e..cf580b3f3df 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -803,18 +803,35 @@ create: }; create2: - '(' field_list ')' opt_create_table_options create3 {} + '(' create2a {} | opt_create_table_options create3 {}; +create2a: + field_list ')' opt_create_table_options create3 {} + | create_select ')' { Select->braces= 1;} union_opt {} + ; + create3: /* empty */ {} - | opt_duplicate opt_as SELECT_SYM + | opt_duplicate opt_as create_select + { Select->braces= 0;} opt_union {} + | opt_duplicate opt_as '(' create_select ')' + { Select->braces= 1;} union_opt {} + ; + +create_select: + SELECT_SYM { LEX *lex=Lex; lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; + switch(lex->sql_command) { + case SQLCOM_INSERT: lex->sql_command=SQLCOM_INSERT_SELECT; break; + case SQLCOM_REPLACE: lex->sql_command=SQLCOM_REPLACE_SELECT; break; + } mysql_init_select(lex); } - select_options select_item_list opt_select_from opt_union {}; + select_options select_item_list opt_select_from + ; opt_as: /* empty */ {} @@ -1490,7 +1507,7 @@ select: select_init: SELECT_SYM select_part2 { Select->braces= 0; } opt_union | - '(' SELECT_SYM select_part2 ')' { Select->braces= 1;} union_opt; + '(' SELECT_SYM select_part2 ')' { Select->braces= 1;} union_opt; select_part2: @@ -2565,7 +2582,7 @@ opt_temporary: insert: INSERT { Lex->sql_command = SQLCOM_INSERT; } insert_lock_option - opt_ignore insert2 + opt_ignore insert2 { set_lock_for_tables($3); } @@ -2576,7 +2593,7 @@ insert: replace: REPLACE { - LEX *lex=Lex; + LEX *lex=Lex; lex->sql_command = SQLCOM_REPLACE; lex->duplicates= DUP_REPLACE; } @@ -2593,7 +2610,7 @@ insert_lock_option: | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; } | DELAYED_SYM { $$= TL_WRITE_DELAYED; } | HIGH_PRIORITY { $$= TL_WRITE; } - ; + ; replace_lock_option: opt_low_priority { $$= $1; } @@ -2613,7 +2630,9 @@ insert_table: }; insert_field_spec: - opt_field_spec insert_values {} + insert_values {} + | '(' ')' insert_values {} + | '(' fields ')' insert_values {} | SET { LEX *lex=Lex; @@ -2634,16 +2653,9 @@ fields: insert_values: VALUES values_list {} - | SELECT_SYM - { - LEX *lex=Lex; - lex->sql_command = (lex->sql_command == SQLCOM_INSERT ? - SQLCOM_INSERT_SELECT : SQLCOM_REPLACE_SELECT); - lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; - mysql_init_select(lex); - } - select_options select_item_list select_from select_lock_type - opt_union {}; + | create_select { Select->braces= 0;} opt_union {} + | '(' create_select ')' { Select->braces= 1;} union_opt {} + ; values_list: values_list ',' no_braces From 048d545a5888821af61ba0493d21c091b1302269 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Tue, 1 Jul 2003 13:29:55 +0300 Subject: [PATCH 086/237] Code/testcase cleanups --- mysql-test/r/insert_select.result | 19 ++++++++----------- mysql-test/r/join_outer.result | 8 ++++++++ mysql-test/t/insert_select.test | 23 ++++++++++------------- mysql-test/t/join_outer.test | 12 ++++++++++++ sql/slave.cc | 3 +-- 5 files changed, 39 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index b49ca3a6c2f..c403ff8532d 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -21,8 +21,7 @@ payoutID 20 22 drop table t1,t2; -DROP TABLE IF EXISTS crash1,crash2; -CREATE TABLE `crash1` ( +CREATE TABLE `t1` ( `numeropost` bigint(20) unsigned NOT NULL default '0', `icone` tinyint(4) unsigned NOT NULL default '0', `numreponse` bigint(20) unsigned NOT NULL auto_increment, @@ -37,7 +36,7 @@ KEY `date` (`date`), KEY `pseudo` (`pseudo`), KEY `numreponse` (`numreponse`) ) TYPE=MyISAM; -CREATE TABLE `crash2` ( +CREATE TABLE `t2` ( `numeropost` bigint(20) unsigned NOT NULL default '0', `icone` tinyint(4) unsigned NOT NULL default '0', `numreponse` bigint(20) unsigned NOT NULL auto_increment, @@ -52,22 +51,20 @@ KEY `date` (`date`), KEY `pseudo` (`pseudo`), KEY `numreponse` (`numreponse`) ) TYPE=MyISAM; -INSERT INTO crash2 +INSERT INTO t2 (numeropost,icone,numreponse,contenu,pseudo,date,ip,signature) VALUES (9,1,56,'test','joce','2001-07-25 13:50:53' ,3649052399,0); -INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip) -SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM crash2 +INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip) +SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM t2 WHERE numeropost=9 ORDER BY numreponse ASC; show variables like '%bulk%'; Variable_name Value bulk_insert_buffer_size 8388608 -INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip) -SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM crash2 +INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip) +SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM t2 WHERE numeropost=9 ORDER BY numreponse ASC; -DROP TABLE IF EXISTS crash1,crash2; -drop table if exists t1; -drop table if exists t2; +DROP TABLE t1,t2; create table t1(a int, unique(a)); insert into t1 values(2); create table t2(a int); diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index 81266f6562e..8f3f82201c3 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -659,3 +659,11 @@ i i i 1 NULL NULL 2 2 2 drop table t1,t2,t3; +create table t1 (f1 integer,f2 integer,f3 integer); +create table t2 (f2 integer,f4 integer); +create table t3 (f3 integer,f5 integer); +select * from t1 +left outer join t2 using (f2) +left outer join t3 using (f3); +Unknown column 'test.t2.f3' in 'on clause' +drop table t1,t2,t3; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index 695f891f678..3b51168269d 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -12,13 +12,13 @@ insert into t2 (payoutID) SELECT payoutID+10 FROM t1; insert ignore into t2 (payoutID) SELECT payoutID+10 FROM t1; select * from t2; drop table t1,t2; + # # bug in bulk insert optimization # test case by Fournier Jocelyn # -DROP TABLE IF EXISTS crash1,crash2; -CREATE TABLE `crash1` ( +CREATE TABLE `t1` ( `numeropost` bigint(20) unsigned NOT NULL default '0', `icone` tinyint(4) unsigned NOT NULL default '0', `numreponse` bigint(20) unsigned NOT NULL auto_increment, @@ -34,7 +34,7 @@ CREATE TABLE `crash1` ( KEY `numreponse` (`numreponse`) ) TYPE=MyISAM; -CREATE TABLE `crash2` ( +CREATE TABLE `t2` ( `numeropost` bigint(20) unsigned NOT NULL default '0', `icone` tinyint(4) unsigned NOT NULL default '0', `numreponse` bigint(20) unsigned NOT NULL auto_increment, @@ -50,30 +50,27 @@ CREATE TABLE `crash2` ( KEY `numreponse` (`numreponse`) ) TYPE=MyISAM; -INSERT INTO crash2 +INSERT INTO t2 (numeropost,icone,numreponse,contenu,pseudo,date,ip,signature) VALUES (9,1,56,'test','joce','2001-07-25 13:50:53' ,3649052399,0); -INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip) -SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM crash2 +INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip) +SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM t2 WHERE numeropost=9 ORDER BY numreponse ASC; show variables like '%bulk%'; -INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip) -SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM crash2 +INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip) +SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM t2 WHERE numeropost=9 ORDER BY numreponse ASC; -DROP TABLE IF EXISTS crash1,crash2; +DROP TABLE t1,t2; - -# Addendum by Guilhem: # Check if a partly-completed INSERT SELECT in a MyISAM table goes # into the binlog -drop table if exists t1; -drop table if exists t2; + create table t1(a int, unique(a)); insert into t1 values(2); create table t2(a int); diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test index e172d54194e..ee7d55d2a4e 100644 --- a/mysql-test/t/join_outer.test +++ b/mysql-test/t/join_outer.test @@ -425,3 +425,15 @@ insert into t2 values(2),(3); insert into t3 values(2),(4); select * from t1 natural left join t2 natural left join t3; drop table t1,t2,t3; + +# +# Test of USING +# +create table t1 (f1 integer,f2 integer,f3 integer); +create table t2 (f2 integer,f4 integer); +create table t3 (f3 integer,f5 integer); +--error 1054 +select * from t1 + left outer join t2 using (f2) + left outer join t3 using (f3); +drop table t1,t2,t3; diff --git a/sql/slave.cc b/sql/slave.cc index fe668900da0..851c6ba4f02 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2146,8 +2146,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) DBUG_ASSERT(rli->sql_thd==thd); if (sql_slave_killed(thd,rli)) { - /* do not forget to free ev ! */ - if (ev) delete ev; + delete ev; return 1; } if (ev) From 9fb7e863ad7d5f701a7b27f75a8b279e19232ef2 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Tue, 1 Jul 2003 14:38:38 +0300 Subject: [PATCH 087/237] Optimized old patches Don't set field to DEFAULT value when set to NULL --- mysql-test/r/insert.result | 2 +- sql/field_conv.cc | 6 +++--- sql/item_strfunc.cc | 17 +++++------------ sql/opt_range.cc | 6 +++++- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index d019cfcbfa9..ebcb7721822 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -65,7 +65,7 @@ insert into t1 values (1), (NULL), (2); select * from t1; id 1 -8 +0 2 drop table t1; drop database if exists foo; diff --git a/sql/field_conv.cc b/sql/field_conv.cc index ce67455881b..db0cc71c6bf 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -118,7 +118,7 @@ set_field_to_null(Field *field) field->reset(); return 0; } - field->set_default(); + field->reset(); if (current_thd->count_cuted_fields) { current_thd->cuted_fields++; // Increment error counter @@ -170,7 +170,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) ((Field_timestamp*) field)->set_time(); return 0; // Ok to set time to NULL } - field->set_default(); + field->reset(); if (field == field->table->next_number_field) return 0; // field is set in handler.cc if (current_thd->count_cuted_fields) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 995d413626c..d18436d2c61 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1546,13 +1546,11 @@ double Item_func_elt::val() return 0.0; double result= args[tmp-1]->val(); - if (args[tmp-1]->is_null()) - return 0.0; - - null_value=0; + null_value= args[tmp-1]->null_value; return result; } + longlong Item_func_elt::val_int() { uint tmp; @@ -1561,13 +1559,11 @@ longlong Item_func_elt::val_int() return 0; int result= args[tmp-1]->val_int(); - if (args[tmp-1]->is_null()) - return 0; - - null_value=0; + null_value= args[tmp-1]->null_value; return result; } + String *Item_func_elt::val_str(String *str) { uint tmp; @@ -1576,10 +1572,7 @@ String *Item_func_elt::val_str(String *str) return NULL; String *result= args[tmp-1]->val_str(str); - if (args[tmp-1]->is_null()) - return NULL; - - null_value=0; + null_value= args[tmp-1]->null_value; return result; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 5704ce6e432..2d949810b63 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2409,7 +2409,11 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref) if (!quick) return 0; if (cp_buffer_from_ref(ref)) - return quick; /* empty range */ + { + if (current_thd->fatal_error) + return 0; // End of memory + return quick; // empty range + } QUICK_RANGE *range= new QUICK_RANGE(); if (!range) From 7b34e1c39d7824057010b3fe48cbec550478bd4c Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Tue, 1 Jul 2003 15:38:11 +0300 Subject: [PATCH 088/237] Updated results after merge --- mysql-test/r/user_var.result | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 0d4f7b401e6..67e55acb29b 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -30,11 +30,15 @@ explain select * from t1 where i=@vv1; table type possible_keys key key_len ref rows Extra t1 ref i i 4 const 1 Using where drop table t1,t2; +select @a:=10, @b:=1, @a > @b, @a < @b; @a:=10 @b:=1 @a > @b @a < @b 10 1 1 0 +select @a:="10", @b:="1", @a > @b, @a < @b; @a:="10" @b:="1" @a > @b @a < @b 10 1 1 0 +select @a:=10, @b:=2, @a > @b, @a < @b; @a:=10 @b:=2 @a > @b @a < @b 10 2 1 0 +select @a:="10", @b:="2", @a > @b, @a < @b; @a:="10" @b:="2" @a > @b @a < @b 10 2 0 1 From 20081b62932e769deaefbb4f42e871b1b04e4ff4 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Tue, 1 Jul 2003 13:17:03 -0400 Subject: [PATCH 089/237] removed --table option (fixed Bug #671) --- client/mysqlbinlog.cc | 54 ++++--------------------------------------- 1 file changed, 4 insertions(+), 50 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 75b875b4f4e..d6da9d81664 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -55,13 +55,11 @@ static ulonglong position = 0; static bool use_remote = 0; static short binlog_flags = 0; static MYSQL* mysql = NULL; -static const char* table = 0; static void dump_local_log_entries(const char* logname); static void dump_remote_log_entries(const char* logname); static void dump_log_entries(const char* logname); static void dump_remote_file(NET* net, const char* fname); -static void dump_remote_table(NET* net, const char* db, const char* table); static void die(const char* fmt, ...); static MYSQL* safe_connect(); @@ -96,8 +94,6 @@ static struct my_option my_long_options[] = {"short-form", 's', "Just show the queries, no extra info", (gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"table", 't', "Get raw table dump using COM_TABLE_DUMB", (gptr*) &table, - (gptr*) &table, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"user", 'u', "Connect to the remote server as username", (gptr*) &user, (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -252,35 +248,6 @@ static void dump_log_entries(const char* logname) dump_local_log_entries(logname); } -static void dump_remote_table(NET* net, const char* db, const char* table) -{ - char buf[1024]; - char * p = buf; - uint table_len = (uint) strlen(table); - uint db_len = (uint) strlen(db); - if (table_len + db_len > sizeof(buf) - 2) - die("Buffer overrun"); - - *p++ = db_len; - memcpy(p, db, db_len); - p += db_len; - *p++ = table_len; - memcpy(p, table, table_len); - - if (simple_command(mysql, COM_TABLE_DUMP, buf, p - buf + table_len, 1)) - die("Error sending the table dump command"); - - for (;;) - { - uint packet_len = my_net_read(net); - if (packet_len == 0) break; // end of file - if (packet_len == packet_error) - die("Error reading packet in table dump"); - my_fwrite(result_file, (byte*)net->read_pos, packet_len, MYF(MY_WME)); - fflush(result_file); - } -} - static int check_master_version(MYSQL* mysql) { MYSQL_RES* res = 0; @@ -516,7 +483,7 @@ int main(int argc, char** argv) MY_INIT(argv[0]); parse_args(&argc, (char***)&argv); - if (!argc && !table) + if (!argc) { usage(); return -1; @@ -525,22 +492,9 @@ int main(int argc, char** argv) if (use_remote) mysql = safe_connect(); - if (table) - { - if (!use_remote) - die("You must specify connection parameter to get table dump"); - char* db = (char*) table; - char* tbl = (char*) strchr(table, '.'); - if (!tbl) - die("You must use database.table syntax to specify the table"); - *tbl++ = 0; - dump_remote_table(&mysql->net, db, tbl); - } - else - { - while (--argc >= 0) - dump_log_entries(*(argv++)); - } + while (--argc >= 0) + dump_log_entries(*(argv++)); + if (result_file != stdout) my_fclose(result_file, MYF(0)); if (use_remote) From c34eec515e2e554024daaacf1bfea406972439b1 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Tue, 1 Jul 2003 14:00:57 -0400 Subject: [PATCH 090/237] made error output more detailed --- client/mysqlbinlog.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 98e03a7e8f1..842dfa28f88 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -346,7 +346,7 @@ static void dump_remote_log_entries(const char* logname) } -static int check_header(IO_CACHE* file) +static int check_header(IO_CACHE* file, const char *fname) { byte header[BIN_LOG_HEADER_SIZE]; byte buf[PROBE_HEADER_LEN]; @@ -357,7 +357,7 @@ static int check_header(IO_CACHE* file) if (my_b_read(file, header, sizeof(header))) die("Failed reading header; Probably an empty file"); if (memcmp(header, BINLOG_MAGIC, sizeof(header))) - die("File is not a binary log file"); + die("File %s is not a binary log file",fname); if (!my_b_read(file, buf, sizeof(buf))) { if (buf[4] == START_EVENT) @@ -390,14 +390,14 @@ static void dump_local_log_entries(const char* logname) if (init_io_cache(file, fd, 0, READ_CACHE, (my_off_t) position, 0, MYF(MY_WME | MY_NABP))) exit(1); - old_format = check_header(file); + old_format = check_header(file,logname); } else { if (init_io_cache(file, fileno(result_file), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) exit(1); - old_format = check_header(file); + old_format = check_header(file,""); if (position) { /* skip 'position' characters from stdout */ From 19da94db0eae3d31a87b21cabb536cc586488f54 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 1 Jul 2003 23:52:59 +0300 Subject: [PATCH 091/237] ha_innodb.cc: Fix a possible hang over the btr0sea.c latch --- sql/ha_innodb.cc | 61 +++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 6e5a14cfb05..3f534f8d6e7 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -982,6 +982,12 @@ innobase_commit( trx = check_trx_exists(thd); + /* Release a possible FIFO ticket and search latch. Since we will + reserve the kernel mutex, we have to release the search system latch + first to obey the latching order. */ + + innobase_release_stat_resources(trx); + /* The flag thd->transaction.all.innodb_active_trans is set to 1 in ::external_lock, ::start_stmt, and innobase_savepoint, and it is only set to 0 in a commit or a rollback. If it is 0 we know there cannot be @@ -1008,9 +1014,7 @@ innobase_commit( /* If we had reserved the auto-inc lock for some table in this SQL statement we release it now */ - innodb_srv_conc_enter_innodb(trx); row_unlock_table_autoinc_for_mysql(trx); - innodb_srv_conc_exit_innodb(trx); } /* Store the current undo_no of the transaction so that we know where to roll back if we have to roll back the next @@ -1019,9 +1023,6 @@ innobase_commit( trx_mark_sql_stat_end(trx); } - /* Release a possible FIFO ticket and search latch */ - innobase_release_stat_resources(trx); - /* Tell the InnoDB server that there might be work for utility threads: */ @@ -1114,18 +1115,20 @@ innobase_rollback( trx = check_trx_exists(thd); + /* Release a possible FIFO ticket and search latch. Since we will + reserve the kernel mutex, we have to release the search system latch + first to obey the latching order. */ + + innobase_release_stat_resources(trx); + if (trx->auto_inc_lock) { /* If we had reserved the auto-inc lock for some table (if we come here to roll back the latest SQL statement) we release it now before a possibly lengthy rollback */ - innodb_srv_conc_enter_innodb(trx); row_unlock_table_autoinc_for_mysql(trx); - innodb_srv_conc_exit_innodb(trx); } - innodb_srv_conc_enter_innodb(trx); - if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) { @@ -1135,11 +1138,6 @@ innobase_rollback( error = trx_rollback_last_sql_stat_for_mysql(trx); } - innodb_srv_conc_exit_innodb(trx); - - /* Release a possible FIFO ticket and search latch */ - innobase_release_stat_resources(trx); - DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); } @@ -1166,17 +1164,17 @@ innobase_rollback_to_savepoint( trx = check_trx_exists(thd); - innodb_srv_conc_enter_innodb(trx); + /* Release a possible FIFO ticket and search latch. Since we will + reserve the kernel mutex, we have to release the search system latch + first to obey the latching order. */ + + innobase_release_stat_resources(trx); error = trx_rollback_to_savepoint_for_mysql(trx, savepoint_name, &mysql_binlog_cache_pos); - innodb_srv_conc_exit_innodb(trx); *binlog_cache_pos = (my_off_t)mysql_binlog_cache_pos; - /* Release a possible FIFO ticket and search latch */ - innobase_release_stat_resources(trx); - DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); } @@ -4496,6 +4494,12 @@ ha_innobase::external_lock( trx->mysql_n_tables_locked = 0; prebuilt->used_in_HANDLER = FALSE; + /* Release a possible FIFO ticket and search latch. Since we + may reserve the kernel mutex, we have to release the search + system latch first to obey the latching order. */ + + innobase_release_stat_resources(trx); + if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) { if (thd->transaction.all.innodb_active_trans != 0) { @@ -4511,11 +4515,6 @@ ha_innobase::external_lock( read_view_close_for_mysql(trx); } } - - /* Here we release the search latch and the InnoDB thread FIFO - ticket if they were reserved. */ - - innobase_release_stat_resources(trx); } DBUG_RETURN(error); @@ -4532,6 +4531,7 @@ innodb_show_status( { String* packet = &thd->packet; char* buf; + trx_t* trx; DBUG_ENTER("innodb_show_status"); @@ -4542,6 +4542,10 @@ innodb_show_status( DBUG_RETURN(-1); } + trx = check_trx_exists(thd); + + innobase_release_stat_resources(trx); + /* We let the InnoDB Monitor to output at most 200 kB of text, add a safety margin of 10 kB for buffer overruns */ @@ -4553,7 +4557,7 @@ innodb_show_status( field_list.push_back(new Item_empty_string("Status", strlen(buf))); - if(send_fields(thd, field_list, 1)) { + if (send_fields(thd, field_list, 1)) { ut_free(buf); @@ -4729,6 +4733,11 @@ ha_innobase::innobase_read_and_init_auto_inc( (trx_t*) current_thd->transaction.all.innobase_tid); ut_a(prebuilt->table); + /* In case MySQL calls this in the middle of a SELECT query, release + possible adaptive hash latch to avoid deadlocks of threads */ + + trx_search_latch_release_if_reserved(prebuilt->trx); + auto_inc = dict_table_autoinc_read(prebuilt->table); if (auto_inc != 0) { @@ -4738,9 +4747,7 @@ ha_innobase::innobase_read_and_init_auto_inc( return(0); } - innodb_srv_conc_enter_innodb(prebuilt->trx); error = row_lock_table_autoinc_for_mysql(prebuilt); - innodb_srv_conc_exit_innodb(prebuilt->trx); if (error != DB_SUCCESS) { error = convert_error_code_to_mysql(error, user_thd); From 34346ecfc965ffd565a71f270cffca6e436775df Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 2 Jul 2003 00:08:29 +0300 Subject: [PATCH 092/237] ha_innobase.cc: Backport from 4.0 of the btr0sea.c latch hang fix --- sql/ha_innobase.cc | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index d1db50dfa89..bafd41ff566 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -718,22 +718,20 @@ innobase_commit( trx = check_trx_exists(thd); + /* Release possible statement level resources */ + innobase_release_stat_resources(trx); + if (trx->auto_inc_lock) { /* If we had reserved the auto-inc lock for some table in this SQL statement, we release it now */ - srv_conc_enter_innodb(trx); row_unlock_table_autoinc_for_mysql(trx); - srv_conc_exit_innodb(trx); } if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { innobase_commit_low(trx); } - - /* Release possible statement level resources */ - innobase_release_stat_resources(trx); trx_mark_sql_stat_end(trx); @@ -797,29 +795,23 @@ innobase_rollback( trx = check_trx_exists(thd); + /* Release possible statement level resources */ + innobase_release_stat_resources(trx); + if (trx->auto_inc_lock) { /* If we had reserved the auto-inc lock for some table in this SQL statement, we release it now */ - srv_conc_enter_innodb(trx); row_unlock_table_autoinc_for_mysql(trx); - srv_conc_exit_innodb(trx); } - srv_conc_enter_innodb(trx); - if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { error = trx_rollback_for_mysql(trx); } else { error = trx_rollback_last_sql_stat_for_mysql(trx); } - srv_conc_exit_innodb(trx); - - /* Release possible statement level resources */ - innobase_release_stat_resources(trx); - trx_mark_sql_stat_end(trx); DBUG_RETURN(convert_error_code_to_mysql(error, NULL)); From c1660e1a23b8d54123c93e92a2ab568cd0d8cdd2 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Wed, 2 Jul 2003 00:10:47 +0300 Subject: [PATCH 093/237] Lot's of clean-ups and fixes for 4.0.14. --- include/my_global.h | 2 +- mysql-test/r/grant.result | 2 + mysql-test/r/insert_select.result | 490 ++++++++++++++++++++++++++++++ mysql-test/r/union.result | 18 ++ mysql-test/t/grant.test | 2 + mysql-test/t/insert_select.test | 16 + mysql-test/t/union.test | 13 + sql/sql_acl.cc | 2 +- sql/sql_parse.cc | 10 +- sql/sql_select.cc | 6 +- sql/sql_union.cc | 3 +- 11 files changed, 552 insertions(+), 12 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 7a8465a0484..03f4db1b5ab 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -263,10 +263,10 @@ C_MODE_END #endif #ifdef HAVE_ATOMIC_ADD #define __SMP__ -#include #ifndef CONFIG_SMP #define CONFIG_SMP #endif +#include #endif #include /* Recommended by debian */ /* We need the following to go around a problem with openssl on solaris */ diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 76080c85511..fccd3715af7 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -106,3 +106,5 @@ delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; drop table t1; +GRANT FILE on mysqltest.* to mysqltest_1@localhost; +Wrong usage of DB GRANT and GLOBAL PRIVILEGES diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index b49ca3a6c2f..5f5a3fb1172 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -80,3 +80,493 @@ Log_name Pos Event_type Server_id Orig_log_pos Info master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3 master-bin.001 79 Query 1 79 use test; insert into t1 select * from t2 drop table t1, t2; +drop table if exists t1, t2; +create table t1 (a int not null); +create table t2 (a int not null); +insert into t1 values (1); +insert into t1 values (a+2); +insert into t1 values (a+3); +insert into t1 values (4),(a+5); +insert into t1 select * from t1; +select * from t1; +a +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +insert into t1 select * from t1 as t2; +select * from t1; +a +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +insert into t2 select * from t1 as t2; +select * from t1; +a +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +insert into t1 select t2.a from t1,t2; +select * from t1; +a +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +2 +3 +4 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +3 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +4 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +5 +drop table t1,t2; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 970e83c6752..929c79b542f 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -96,6 +96,13 @@ a b select found_rows(); found_rows() 6 +select sql_calc_found_rows a,b from t1 union all select a,b from t2 limit 2; +a b +1 a +2 b +select found_rows(); +found_rows() +6 explain select a,b from t1 union all select a,b from t2; table type possible_keys key key_len ref rows Extra t1 ALL NULL NULL NULL NULL 4 @@ -259,3 +266,14 @@ uid rl g1 cid gg uid rl g1 cid gg 1 NULL V1 NULL 1 drop table t1,t2,t3,t4,t5,t6; +CREATE TABLE t1 (a int not null, b char (10) not null); +insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); +CREATE TABLE t2 (a int not null, b char (10) not null); +insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e'); +create table t3 select a,b from t1 union select a,b from t2; +create table t4 (select a,b from t1) union (select a,b from t2) limit 2; +insert into t4 select a,b from t1 union select a,b from t2; +insert into t3 (select a,b from t1) union (select a,b from t2) limit 2; +select * from t3; +select * from t4; +drop table t1,t2,t3,t4; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index b18ae941c26..a93339a3ad6 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -72,3 +72,5 @@ delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; drop table t1; +--error 1054 +GRANT FILE on mysqltest.* to mysqltest_1@localhost; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index 695f891f678..2bebd4e86dd 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -87,3 +87,19 @@ let $VERSION=`select version()`; --replace_result $VERSION VERSION show binlog events; drop table t1, t2; +drop table if exists t1, t2; +create table t1 (a int not null); +create table t2 (a int not null); +insert into t1 values (1); +insert into t1 values (a+2); +insert into t1 values (a+3); +insert into t1 values (4),(a+5); +insert into t1 select * from t1; +select * from t1; +insert into t1 select * from t1 as t2; +select * from t1; +insert into t2 select * from t1 as t2; +select * from t1; +insert into t1 select t2.a from t1,t2; +select * from t1; +drop table t1,t2; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 7262b8f78d7..5f7eba83755 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -23,6 +23,8 @@ select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 g explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc; (select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2; select found_rows(); +select sql_calc_found_rows a,b from t1 union all select a,b from t2 limit 2; +select found_rows(); # # Test some error conditions with UNION @@ -157,3 +159,14 @@ SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left (SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t3.must IS NOT NULL AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test") UNION (SELECT t4.uid, t5.rl, t3.gn as g1, t4.cid, t4.gid as gg FROM t3, t6, t1, t4 left join t5 on t5.rid = t4.rid left join t2 on t2.cid = t4.cid WHERE t3.gid=t4.gid AND t6.uid = t4.uid AND t6.uc = t1.cid AND t1.cv = "dummy" AND t6.un = "test"); drop table t1,t2,t3,t4,t5,t6; +CREATE TABLE t1 (a int not null, b char (10) not null); +insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); +CREATE TABLE t2 (a int not null, b char (10) not null); +insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e'); +create table t3 select a,b from t1 union select a,b from t2; +create table t4 (select a,b from t1) union (select a,b from t2) limit 2; +insert into t4 select a,b from t1 union select a,b from t2; +insert into t3 (select a,b from t1) union (select a,b from t2) limit 2; +select * from t3; +select * from t4; +drop table t1,t2,t3,t4; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3e9abc0410d..90497cc8b43 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2325,7 +2325,7 @@ int mysql_grant (THD *thd, const char *db, List &list, } else { - net_printf(&thd->net,ER_WRONG_USAGE,"DB GRANT","GLOBAL PRIVILEGEY"); + net_printf(&thd->net,ER_WRONG_USAGE,"DB GRANT","GLOBAL PRIVILEGES"); result= -1; } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4570576afef..1ac4120187b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3386,14 +3386,18 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, tables ; tables=tables->next) { - if (!strcmp(alias_str,tables->alias) && !strcmp(ptr->db, tables->db)) + if (ptr->db_length == tables->db_length && !memcmp(ptr->db, tables->db, ptr->db_length)) { if ((thd->lex.sql_command & (SQLCOM_INSERT_SELECT | SQLCOM_REPLACE_SELECT)) && (tables->lock_type & (TL_WRITE_CONCURRENT_INSERT | TL_WRITE_LOW_PRIORITY | TL_WRITE_DELAYED | TL_WRITE))) - thd->lex.select->options |= OPTION_BUFFER_RESULT; - else + { + if (ptr->real_name_length == tables->real_name_length && + !memcmp(ptr->real_name, tables->real_name,ptr->real_name_length)) + thd->lex.select->options |= OPTION_BUFFER_RESULT; + } + else if (!strcmp(alias_str,tables->alias)) { net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */ DBUG_RETURN(0); /* purecov: tested */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6c2d06051d4..eb29946a3d7 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -974,11 +974,7 @@ mysql_select(THD *thd,TABLE_LIST *tables,List &fields,COND *conds, thd->select_limit)) { if (!join.join_tab[join.const_tables].select->quick) - error= return_zero_rows(&join, result, tables, fields, - 0, select_options, - "Impossible WHERE noticed after reading const tables", - having,procedure); - goto err; + goto err; } } join.having=having; // Actually a parameter diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 407bf64d628..bd7bc7027d3 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -33,7 +33,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) TABLE *table; int describe=(lex->select_lex.options & SELECT_DESCRIBE) ? 1 : 0; int res; - bool found_rows_for_union= 0; + bool found_rows_for_union= lex->select_lex.options & OPTION_FOUND_ROWS; TABLE_LIST result_table_list; TABLE_LIST *first_table=(TABLE_LIST *)lex->select_lex.table_list.first; TMP_TABLE_PARAM tmp_table_param; @@ -63,7 +63,6 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) */ lex_sl= sl; order= (ORDER *) lex_sl->order_list.first; - found_rows_for_union = lex->select_lex.options & OPTION_FOUND_ROWS && sl->select_limit; // This is done to eliminate unnecessary slowing down of the first query if (!order || !describe) last_sl->next=0; // Remove this extra element From fb39821e94b7f921000a40c42efdcdb8c4f28d6d Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Wed, 2 Jul 2003 01:24:05 +0300 Subject: [PATCH 094/237] Some fixes for CREATE / INSERT FROM UNIO >.. --- mysql-test/r/union.result | 30 ++++++++++++++++++++++++++++-- mysql-test/t/grant.test | 2 +- mysql-test/t/union.test | 4 ++-- sql/sql_yacc.yy | 9 +++------ 4 files changed, 34 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 929c79b542f..2072b045563 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -271,9 +271,35 @@ insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); CREATE TABLE t2 (a int not null, b char (10) not null); insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e'); create table t3 select a,b from t1 union select a,b from t2; -create table t4 (select a,b from t1) union (select a,b from t2) limit 2; +create table t4 (select a,b from t1) union (select a,b from t2); insert into t4 select a,b from t1 union select a,b from t2; -insert into t3 (select a,b from t1) union (select a,b from t2) limit 2; +insert into t3 (select a,b from t1) union (select a,b from t2); select * from t3; +a b +1 a +2 b +3 c +4 d +5 f +6 e +1 a +2 b +3 c +4 d +5 f +6 e select * from t4; +a b +1 a +2 b +3 c +4 d +5 f +6 e +1 a +2 b +3 c +4 d +5 f +6 e drop table t1,t2,t3,t4; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index a93339a3ad6..5b20354336c 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -72,5 +72,5 @@ delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; drop table t1; ---error 1054 +--error 1221 GRANT FILE on mysqltest.* to mysqltest_1@localhost; diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 5f7eba83755..dcf2f79e5bf 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -164,9 +164,9 @@ insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); CREATE TABLE t2 (a int not null, b char (10) not null); insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e'); create table t3 select a,b from t1 union select a,b from t2; -create table t4 (select a,b from t1) union (select a,b from t2) limit 2; +create table t4 (select a,b from t1) union (select a,b from t2); insert into t4 select a,b from t1 union select a,b from t2; -insert into t3 (select a,b from t1) union (select a,b from t2) limit 2; +insert into t3 (select a,b from t1) union (select a,b from t2); select * from t3; select * from t4; drop table t1,t2,t3,t4; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8b0e3dfe8d7..cf580b3f3df 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -597,7 +597,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_to_table_list table_to_table opt_table_list opt_as handler_rkey_function handler_read_or_scan single_multi table_wild_list table_wild_one opt_wild opt_union union_list - precision union_option + precision union_option opt_and END_OF_INPUT %type @@ -2640,9 +2640,7 @@ insert_field_spec: lex->many_values.push_back(lex->insert_list)) YYABORT; } - ident_eq_list - | select_for_insert {} - ; + ident_eq_list; opt_field_spec: /* empty */ { } @@ -2651,8 +2649,7 @@ opt_field_spec: fields: fields ',' insert_ident { Lex->field_list.push_back($3); } - | insert_ident { Lex->field_list.push_back($1); } - ; + | insert_ident { Lex->field_list.push_back($1); }; insert_values: VALUES values_list {} From f67308f6127d9a453b12188daba369e62101bfa5 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 2 Jul 2003 01:57:40 +0300 Subject: [PATCH 095/237] ha_innodb.cc: Remove still some potential hangs over the btr0sea.c semaphore --- sql/ha_innodb.cc | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 3f534f8d6e7..8924ff3a97d 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -663,6 +663,8 @@ ha_innobase::init_table_handle_for_HANDLER(void) prebuilt = (row_prebuilt_t*)innobase_prebuilt; + innobase_release_stat_resources(prebuilt->trx); + /* If the transaction is not started yet, start it */ trx_start_if_not_started_noninline(prebuilt->trx); @@ -1206,6 +1208,12 @@ innobase_savepoint( trx = check_trx_exists(thd); + /* Release a possible FIFO ticket and search latch. Since we will + reserve the kernel mutex, we have to release the search system latch + first to obey the latching order. */ + + innobase_release_stat_resources(trx); + /* Setting a savepoint starts a transaction inside InnoDB since it allocates resources for it (memory to store the savepoint name, for example) */ @@ -1219,26 +1227,28 @@ innobase_savepoint( } /********************************************************************* -Frees a possible InnoDB trx object associated with the current -THD. */ +Frees a possible InnoDB trx object associated with the current THD. */ int innobase_close_connection( /*======================*/ - /* out: 0 or error number */ - THD* thd) /* in: handle to the MySQL thread of the user - whose transaction should be rolled back */ + /* out: 0 or error number */ + THD* thd) /* in: handle to the MySQL thread of the user + whose transaction should be rolled back */ { - if (NULL != thd->transaction.all.innobase_tid) { + trx_t* trx; - trx_rollback_for_mysql((trx_t*) - (thd->transaction.all.innobase_tid)); - trx_free_for_mysql((trx_t*) - (thd->transaction.all.innobase_tid)); - thd->transaction.all.innobase_tid = NULL; - } + trx = (trx_t*)thd->transaction.all.innobase_tid; - return(0); + if (NULL != trx) { + innobase_rollback(thd, (void*)trx); + + trx_free_for_mysql(trx); + + thd->transaction.all.innobase_tid = NULL; + } + + return(0); } /********************************************************************** @@ -1497,6 +1507,8 @@ ha_innobase::close(void) /*====================*/ /* out: error number */ { + trx_t* trx; + DBUG_ENTER("ha_innobase::close"); row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt); From 6ae8ff3cc86a96727aeff8f5379f362543aa960f Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 2 Jul 2003 02:01:11 +0300 Subject: [PATCH 096/237] ha_innodb.cc: Cleanup --- sql/ha_innodb.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 8924ff3a97d..2cc64b18706 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1507,8 +1507,6 @@ ha_innobase::close(void) /*====================*/ /* out: error number */ { - trx_t* trx; - DBUG_ENTER("ha_innobase::close"); row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt); From 785b17db9614c8d6e57380a72403718207338b84 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 2 Jul 2003 04:57:31 +0300 Subject: [PATCH 097/237] lock0lock.c: Fix a latching order violation in the previous (2003-06-15) push: could lead to a hang on the btr0sea.c semaphore --- innobase/lock/lock0lock.c | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index fecb1f95c68..397a8158bee 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -579,6 +579,10 @@ lock_clust_rec_cons_read_sees( ut_ad(index->type & DICT_CLUSTERED); ut_ad(page_rec_is_user_rec(rec)); + /* NOTE that we call this function while holding the search + system latch. To obey the latching order we must NOT reserve the + kernel mutex here! */ + trx_id = row_get_rec_trx_id(rec, index); if (read_view_sees_trx_id(view, trx_id)) { @@ -586,15 +590,6 @@ lock_clust_rec_cons_read_sees( return(TRUE); } - if (!lock_check_trx_id_sanity(trx_id, rec, index, FALSE)) { - /* Trying to get the 'history' of a corrupt record is bound - to fail: let us try to use the record itself in the query */ - fprintf(stderr, -"InnoDB: We try to access the corrupt record in the query anyway.\n"); - - return(TRUE); - } - return(FALSE); } @@ -624,6 +619,10 @@ lock_sec_rec_cons_read_sees( ut_ad(!(index->type & DICT_CLUSTERED)); ut_ad(page_rec_is_user_rec(rec)); + /* NOTE that we might call this function while holding the search + system latch. To obey the latching order we must NOT reserve the + kernel mutex here! */ + if (recv_recovery_is_on()) { return(FALSE); @@ -633,16 +632,6 @@ lock_sec_rec_cons_read_sees( if (ut_dulint_cmp(max_trx_id, view->up_limit_id) >= 0) { - if (!lock_check_trx_id_sanity(max_trx_id, rec, index, FALSE)) { - /* Trying to get the 'history' of a corrupt record is - bound to fail: let us try to use the record itself in - the query */ - fprintf(stderr, -"InnoDB: We try to access the corrupt record in the query anyway.\n"); - - return(TRUE); - } - return(FALSE); } From 1b11e4afad043d92d9a26e713e3a81847038a53a Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Wed, 2 Jul 2003 10:56:39 +0300 Subject: [PATCH 098/237] Fixed password check problem on windows (Bug #464) --- 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 3b3da6d35b3..5857dc50c4f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -500,7 +500,7 @@ check_connections(THD *thd) #if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread) /* Fast local hostname resolve for Win32 */ if (!strcmp(thd->ip,"127.0.0.1")) - thd->host=(char*) localhost; + thd->host= thd->host_or_ip= (char*) localhost; else #endif if (!(specialflag & SPECIAL_NO_RESOLVE)) From 00c557b9c4e77845e7dfefb4f01962d5f38ecd00 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 2 Jul 2003 13:03:59 +0300 Subject: [PATCH 099/237] sync0sync.c: Make execution with UNIV_SYNC_DEBUG faster --- innobase/sync/sync0sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/innobase/sync/sync0sync.c b/innobase/sync/sync0sync.c index 32615ce88ac..773b239189c 100644 --- a/innobase/sync/sync0sync.c +++ b/innobase/sync/sync0sync.c @@ -159,7 +159,7 @@ struct sync_thread_struct{ }; /* Number of slots reserved for each OS thread in the sync level array */ -#define SYNC_THREAD_N_LEVELS 10000 +#define SYNC_THREAD_N_LEVELS 250 struct sync_level_struct{ void* latch; /* pointer to a mutex or an rw-lock; NULL means that From 0ba742ed3be55ff062a73fdb86104925c7550d26 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 2 Jul 2003 13:15:45 +0300 Subject: [PATCH 100/237] innodb.test, innodb.result: Remove nondeterministic EXPLAIN SELECT which gives on 64-bit platforms a slightly different estimate (sometimes we should study why we get different results on 64-bit and 32-bit) --- mysql-test/r/innodb.result | 3 --- mysql-test/t/innodb.test | 1 - 2 files changed, 4 deletions(-) diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 465d4faf0bc..bb237e2e406 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1238,9 +1238,6 @@ explain select * from t1 where c between 1 and 10000; table type possible_keys key key_len ref rows Extra t1 range c c 5 NULL 1 Using where update t1 set c=a; -explain select * from t1 where c between 1 and 10000; -table type possible_keys key key_len ref rows Extra -t1 ALL c NULL NULL NULL 27682 Using where drop table t1,t2; create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb; insert into t1 (id) values (null),(null),(null),(null),(null); diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index cf203d87c8b..05b4370d0e0 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -830,7 +830,6 @@ insert into t1 (a) select b from t2; select count(*) from t1; explain select * from t1 where c between 1 and 10000; update t1 set c=a; -explain select * from t1 where c between 1 and 10000; drop table t1,t2; # From 1df6492c7d5036e0553191d8da86df7db220a70c Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Wed, 2 Jul 2003 14:57:40 +0300 Subject: [PATCH 101/237] Fix for a problem with : CREATE / INSERT ... (SELECT ...) UNION (SELECT ...) LIMIT; --- mysql-test/r/union.result | 12 ++---------- mysql-test/t/union.test | 4 ++-- sql/sql_yacc.yy | 4 +++- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 2072b045563..51d9f2d17ca 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -271,9 +271,9 @@ insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); CREATE TABLE t2 (a int not null, b char (10) not null); insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e'); create table t3 select a,b from t1 union select a,b from t2; -create table t4 (select a,b from t1) union (select a,b from t2); +create table t4 (select a,b from t1) union (select a,b from t2) limit 2; insert into t4 select a,b from t1 union select a,b from t2; -insert into t3 (select a,b from t1) union (select a,b from t2); +insert into t3 (select a,b from t1) union (select a,b from t2) limit 2; select * from t3; a b 1 a @@ -284,18 +284,10 @@ a b 6 e 1 a 2 b -3 c -4 d -5 f -6 e select * from t4; a b 1 a 2 b -3 c -4 d -5 f -6 e 1 a 2 b 3 c diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index dcf2f79e5bf..5f7eba83755 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -164,9 +164,9 @@ insert into t1 values(1,'a'),(2,'b'),(3,'c'),(3,'c'); CREATE TABLE t2 (a int not null, b char (10) not null); insert into t2 values (3,'c'),(4,'d'),(5,'f'),(6,'e'); create table t3 select a,b from t1 union select a,b from t2; -create table t4 (select a,b from t1) union (select a,b from t2); +create table t4 (select a,b from t1) union (select a,b from t2) limit 2; insert into t4 select a,b from t1 union select a,b from t2; -insert into t3 (select a,b from t1) union (select a,b from t2); +insert into t3 (select a,b from t1) union (select a,b from t2) limit 2; select * from t3; select * from t4; drop table t1,t2,t3,t4; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index cf580b3f3df..cf94532ac86 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -762,7 +762,7 @@ create: lex->create_info.db_type= (enum db_type) lex->thd->variables.table_type; } create2 - {} + {Lex->select= &Lex->select_lex;} | CREATE opt_unique_or_fulltext INDEX ident ON table_ident { LEX *lex=Lex; @@ -2585,6 +2585,7 @@ insert: opt_ignore insert2 { set_lock_for_tables($3); + Lex->select= &Lex->select_lex; } insert_field_spec {} @@ -2600,6 +2601,7 @@ replace: replace_lock_option insert2 { set_lock_for_tables($3); + Lex->select= &Lex->select_lex; } insert_field_spec {} From dcd13cf264ee07f2b7014bc1fdedd7de98689400 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Wed, 2 Jul 2003 17:12:50 +0200 Subject: [PATCH 102/237] bug #504: in "datetime op int" comparison int wasn't converted to datetime --- mysql-test/r/type_datetime.result | 9 ++++++++- mysql-test/t/type_datetime.test | 5 ++++- sql/item_cmpfunc.cc | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 4785f790069..5df4f355cfb 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -52,10 +52,17 @@ a 0000-00-00 00:00:00 drop table t1; create table t1 (id int, dt datetime); -insert into t1 values (1,"2001-08-14 00:00:00"),(2,"2001-08-15 00:00:00"),(3,"2001-08-16 00:00:00"); +insert into t1 values (1,"2001-08-14 00:00:00"),(2,"2001-08-15 00:00:00"),(3,"2001-08-16 00:00:00"),(4,"2003-09-15 01:20:30"); select * from t1 where dt='2001-08-14 00:00:00' and dt = if(id=1,'2001-08-14 00:00:00','1999-08-15'); id dt 1 2001-08-14 00:00:00 +create index dt on t1 (dt); +select * from t1 where dt > 20021020; +id dt +4 2003-09-15 01:20:30 +select * from t1 ignore index (dt) where dt > 20021020; +id dt +4 2003-09-15 01:20:30 drop table t1; CREATE TABLE `t1` ( `date` datetime NOT NULL default '0000-00-00 00:00:00', diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index f5103958979..51b65d00243 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -36,8 +36,11 @@ drop table t1; # create table t1 (id int, dt datetime); -insert into t1 values (1,"2001-08-14 00:00:00"),(2,"2001-08-15 00:00:00"),(3,"2001-08-16 00:00:00"); +insert into t1 values (1,"2001-08-14 00:00:00"),(2,"2001-08-15 00:00:00"),(3,"2001-08-16 00:00:00"),(4,"2003-09-15 01:20:30"); select * from t1 where dt='2001-08-14 00:00:00' and dt = if(id=1,'2001-08-14 00:00:00','1999-08-15'); +create index dt on t1 (dt); +select * from t1 where dt > 20021020; +select * from t1 ignore index (dt) where dt > 20021020; drop table t1; # diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 78a63d84c61..5d47fa302f3 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -46,7 +46,7 @@ longlong Item_func_not::val_int() static bool convert_constant_item(Field *field, Item **item) { - if ((*item)->const_item() && (*item)->type() != Item::INT_ITEM) + if ((*item)->const_item()) { if (!(*item)->save_in_field(field, 1) && !((*item)->null_value)) From 55e046a807d3dc27420b18f5939cc0b96271b21a Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Wed, 2 Jul 2003 16:56:27 -0400 Subject: [PATCH 103/237] fixed bug #672 --- client/mysqlbinlog.cc | 2 +- sql/sql_parse.cc | 3 ++- sql/sql_repl.cc | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 75b875b4f4e..109e9095b7a 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -360,7 +360,7 @@ static void dump_remote_log_entries(const char* logname) len = net_safe_read(mysql); if (len == packet_error) die("Error reading packet from server: %s", mysql_error(mysql)); - if (len == 1 && net->read_pos[0] == 254) + if (len < 8 && net->read_pos[0] == 254) break; // end of data DBUG_PRINT("info",( "len= %u, net->read_pos[5] = %d\n", len, net->read_pos[5])); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d9060b4b26e..233644feb4e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1147,7 +1147,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, pos = uint4korr(packet); flags = uint2korr(packet + 4); thd->server_id=0; /* avoid suicide */ - kill_zombie_dump_threads(slave_server_id = uint4korr(packet+6)); + if ((slave_server_id= uint4korr(packet+6))) + kill_zombie_dump_threads(slave_server_id); thd->server_id = slave_server_id; mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags); unregister_slave(thd,1,1); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 283dd20a56c..bc833d7e759 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -503,6 +503,11 @@ Increase max_allowed_packet on master"; case LOG_READ_EOF: DBUG_PRINT("wait",("waiting for data in binary log")); + if (thd->server_id==0) + { + pthread_mutex_unlock(log_lock); + goto end; + } if (!thd->killed) { /* Note that the following call unlocks lock_log */ @@ -590,6 +595,7 @@ Increase max_allowed_packet on master"; } } +end: end_io_cache(&log); (void)my_close(file, MYF(MY_WME)); @@ -600,7 +606,7 @@ Increase max_allowed_packet on master"; pthread_mutex_unlock(&LOCK_thread_count); DBUG_VOID_RETURN; - err: +err: thd->proc_info = "waiting to finalize termination"; end_io_cache(&log); /* From 6bbe7b80758e66d3c162a900bafbe4ea2c090d11 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Wed, 2 Jul 2003 19:08:31 -0400 Subject: [PATCH 104/237] add comment for BUG 672 --- sql/sql_parse.cc | 2 +- sql/sql_repl.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b2e1e56dc8f..c5b08c6121a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1160,7 +1160,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, pos = uint4korr(packet); flags = uint2korr(packet + 4); thd->server_id=0; /* avoid suicide */ - if ((slave_server_id= uint4korr(packet+6))) + if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0 kill_zombie_dump_threads(slave_server_id); thd->server_id = slave_server_id; mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 12228ec3ac8..bf4b1eb0c70 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -522,7 +522,7 @@ Increase max_allowed_packet on master"; case LOG_READ_EOF: DBUG_PRINT("wait",("waiting for data in binary log")); - if (thd->server_id==0) + if (thd->server_id==0) // for mysqlbinlog (mysqlbinlog.server_id==0) { pthread_mutex_unlock(log_lock); goto end; From 7f4fe0b0f3e1b1d8c862fb2be6d41f3635cf6bd9 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 3 Jul 2003 02:08:33 +0300 Subject: [PATCH 105/237] innodb.result, innodb.test: Remove all nondeterministic tests from innodb.test; but I have to study why on 64 bits we get different estimates --- mysql-test/r/innodb.result | 51 -------------------------------------- mysql-test/t/innodb.test | 16 ------------ 2 files changed, 67 deletions(-) diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index bb237e2e406..6ab55bbf924 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -157,11 +157,6 @@ level id parent_id optimize table t1; Table Op Msg_type Msg_text test.t1 optimize status OK -show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t1 0 PRIMARY 1 id A 87 NULL NULL BTREE -t1 1 parent_id 1 parent_id A 43 NULL NULL BTREE -t1 1 level 1 level A 6 NULL NULL BTREE drop table t1; CREATE TABLE t1 ( gesuchnr int(11) DEFAULT '0' NOT NULL, @@ -200,9 +195,6 @@ insert into t1 values (3,""), (4,"testing"); analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK -show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t1 1 skr 1 a A 3 NULL NULL YES BTREE drop table t1; create table t1 (a int,b varchar(20),key(a)) type=innodb; insert into t1 values (1,""), (2,"testing"); @@ -343,14 +335,6 @@ user_id name phone ref_email detail drop table t1; CREATE TABLE t1 (a int not null, b int not null,c int not null, key(a),primary key(a,b), unique(c),key(a),unique(b)); -show index from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t1 0 PRIMARY 1 a A NULL NULL NULL BTREE -t1 0 PRIMARY 2 b A 0 NULL NULL BTREE -t1 0 c 1 c A 0 NULL NULL BTREE -t1 0 b 1 b A 0 NULL NULL BTREE -t1 1 a 1 a A NULL NULL NULL BTREE -t1 1 a_2 1 a A NULL NULL NULL BTREE drop table t1; create table t1 (col1 int not null, col2 char(4) not null, primary key(col1)); alter table t1 type=innodb; @@ -713,9 +697,6 @@ hello 1 optimize table t1; Table Op Msg_type Msg_text test.t1 optimize status OK -show keys from t1; -Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t1 0 PRIMARY 1 a A 2 NULL NULL BTREE drop table t1; create table t1 (i int, j int ) TYPE=innodb; insert into t1 values (1,2); @@ -745,9 +726,6 @@ a DROP TABLE t1; create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h int, i int, j int, k int, l int, m int, n int, o int, p int, q int, r int, s int, t int, u int, v int, w int, x int, y int, z int, a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, b1 int, b2 int, b3 int, b4 int, b5 int, b6 int) type = innodb; insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); -explain select * from t1 where a > 0 and a < 50; -table type possible_keys key key_len ref rows Extra -t1 range PRIMARY PRIMARY 4 NULL 1 Using where drop table t1; create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=innodb; insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL'); @@ -835,8 +813,6 @@ create table mysqltest.t3 (a int not null) type= heap; insert into mysqltest.t3 values(1); commit; drop database mysqltest; -show tables from mysqltest; -Got one of the listed errors set autocommit=0; create table t1 (a int not null) type= innodb; insert into t1 values(1),(2); @@ -869,30 +845,6 @@ a drop table t1; create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) type=innodb; insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4); -explain select * from t1 order by a; -table type possible_keys key key_len ref rows Extra -t1 index NULL PRIMARY 4 NULL 4 -explain select * from t1 order by b; -table type possible_keys key key_len ref rows Extra -t1 index NULL b 4 NULL 4 -explain select * from t1 order by c; -table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 4 Using filesort -explain select a from t1 order by a; -table type possible_keys key key_len ref rows Extra -t1 index NULL PRIMARY 4 NULL 4 Using index -explain select b from t1 order by b; -table type possible_keys key key_len ref rows Extra -t1 index NULL b 4 NULL 4 Using index -explain select a,b from t1 order by b; -table type possible_keys key key_len ref rows Extra -t1 index NULL b 4 NULL 4 Using index -explain select a,b from t1; -table type possible_keys key key_len ref rows Extra -t1 index NULL b 4 NULL 4 Using index -explain select a,b,c from t1; -table type possible_keys key key_len ref rows Extra -t1 ALL NULL NULL NULL NULL 4 drop table t1; create table t1 (t int not null default 1, key (t)) type=innodb; desc t1; @@ -1234,9 +1186,6 @@ insert into t1 (a) select b from t2; select count(*) from t1; count(*) 29267 -explain select * from t1 where c between 1 and 10000; -table type possible_keys key key_len ref rows Extra -t1 range c c 5 NULL 1 Using where update t1 set c=a; drop table t1,t2; create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 05b4370d0e0..7b36a675a31 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -46,7 +46,6 @@ select * from t1 where parent_id=102; select level,id from t1 where level=1; select level,id,parent_id from t1 where level=1; optimize table t1; -show keys from t1; drop table t1; # @@ -84,7 +83,6 @@ select * from t1; create index skr on t1 (a); insert into t1 values (3,""), (4,"testing"); analyze table t1; -show keys from t1; drop table t1; @@ -222,7 +220,6 @@ drop table t1; CREATE TABLE t1 (a int not null, b int not null,c int not null, key(a),primary key(a,b), unique(c),key(a),unique(b)); -show index from t1; drop table t1; # @@ -396,7 +393,6 @@ create table t1 (a varchar(100) not null, primary key(a), b int not null) type=i insert into t1 values("hello",1),("world",2); select * from t1 order by b desc; optimize table t1; -show keys from t1; drop table t1; # @@ -441,7 +437,6 @@ DROP TABLE t1; create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h int, i int, j int, k int, l int, m int, n int, o int, p int, q int, r int, s int, t int, u int, v int, w int, x int, y int, z int, a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int, a9 int, b1 int, b2 int, b3 int, b4 int, b5 int, b6 int) type = innodb; insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); -explain select * from t1 where a > 0 and a < 50; drop table t1; # @@ -519,8 +514,6 @@ insert into mysqltest.t3 values(1); commit; drop database mysqltest; # Don't check error message ---error 12,12 -show tables from mysqltest; # # Test truncate table with and without auto_commit @@ -558,14 +551,6 @@ drop table t1; create table t1 (a int not null, b int not null, c int not null, primary key (a),key(b)) type=innodb; insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4); -explain select * from t1 order by a; -explain select * from t1 order by b; -explain select * from t1 order by c; -explain select a from t1 order by a; -explain select b from t1 order by b; -explain select a,b from t1 order by b; -explain select a,b from t1; -explain select a,b,c from t1; drop table t1; # @@ -828,7 +813,6 @@ insert into t1 (a) select b from t2; insert into t2 (a) select b from t1; insert into t1 (a) select b from t2; select count(*) from t1; -explain select * from t1 where c between 1 and 10000; update t1 set c=a; drop table t1,t2; From b3f153507e6503c17db0579105c3b92d2fc0bceb Mon Sep 17 00:00:00 2001 From: "pem@mysql.com" <> Date: Thu, 3 Jul 2003 01:08:34 +0200 Subject: [PATCH 106/237] Added missing (char*) casts in bzero calls. (Needed for platforms with the traditional bzero prototype.) Fixes BUG#460. --- sql/slave.cc | 4 ++-- sql/slave.h | 2 +- sql/sql_acl.cc | 4 ++-- sql/sql_lex.cc | 2 +- sql/sql_yacc.yy | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 851c6ba4f02..bc9528ae2c7 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1710,8 +1710,8 @@ st_relay_log_info::st_relay_log_info() last_slave_error[0]=0; - bzero(&info_file,sizeof(info_file)); - bzero(&cache_buf, sizeof(cache_buf)); + bzero((char *)&info_file,sizeof(info_file)); + bzero((char *)&cache_buf, sizeof(cache_buf)); pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&log_space_lock, MY_MUTEX_INIT_FAST); diff --git a/sql/slave.h b/sql/slave.h index 66000f45e69..6a73c86d304 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -282,7 +282,7 @@ typedef struct st_master_info abort_slave(0),slave_running(0), slave_run_id(0) { host[0] = 0; user[0] = 0; password[0] = 0; - bzero(&file, sizeof(file)); + bzero((char *)&file, sizeof(file)); pthread_mutex_init(&run_lock, MY_MUTEX_INIT_FAST); pthread_mutex_init(&data_lock, MY_MUTEX_INIT_FAST); pthread_cond_init(&data_cond, NULL); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 90497cc8b43..225d84f4751 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -275,7 +275,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) else { user.ssl_type=SSL_TYPE_NONE; - bzero(&(user.user_resource),sizeof(user.user_resource)); + bzero((char *)&(user.user_resource),sizeof(user.user_resource)); #ifndef TO_BE_REMOVED if (table->fields <= 13) { // Without grant @@ -506,7 +506,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, *priv_user=(char*) user; DBUG_ENTER("acl_getroot"); - bzero(mqh,sizeof(USER_RESOURCES)); + bzero((char *)mqh,sizeof(USER_RESOURCES)); if (!initialized) { // If no data allow anything diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index d5a225d95dd..d62edf83c11 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -152,7 +152,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE); lex->slave_thd_opt=0; lex->sql_command=SQLCOM_END; - bzero(&lex->mi,sizeof(lex->mi)); + bzero((char *)&lex->mi,sizeof(lex->mi)); return lex; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index cf94532ac86..4022dd89797 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3685,7 +3685,7 @@ grant: lex->select->db= 0; lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; - bzero(&(lex->mqh),sizeof(lex->mqh)); + bzero((char *)&(lex->mqh),sizeof(lex->mqh)); } grant_privileges ON opt_table TO_SYM user_list require_clause grant_options From ace8a06323af77401cc5bcdc8b17043fc6081b66 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Thu, 3 Jul 2003 01:08:36 +0200 Subject: [PATCH 107/237] I committed the same changeset in my tree yesterday, but broke the tree since, so I commit again in a fresh tree. Fix for bug#763 (Relay_log_space too big by 4 bytes), plus comments and DBUG_PRINT, and we don't start replication if --bootstrap. --- mysql-test/r/rpl_log.result | 2 +- mysql-test/r/rpl_log_pos.result | 2 +- sql/mysqld.cc | 2 ++ sql/slave.cc | 27 +++++++++++++++++++++++++-- sql/sql_acl.cc | 2 +- sql/sql_repl.cc | 19 +++++++++++++++++++ 6 files changed, 49 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 316bf1f3dd0..616ad319880 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -93,6 +93,6 @@ slave-bin.002 62 Query 1 168 use test; insert into t1 values (1) slave-bin.002 122 Query 1 228 use test; drop table t1 show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1563 master-bin.002 Yes Yes 0 0 276 1567 +127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1563 master-bin.002 Yes Yes 0 0 276 1563 show binlog events in 'slave-bin.005' from 4; Error when executing command SHOW BINLOG EVENTS: Could not find target log diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result index 3224e84fa31..f7e59e55577 100644 --- a/mysql-test/r/rpl_log_pos.result +++ b/mysql-test/r/rpl_log_pos.result @@ -9,7 +9,7 @@ File Position Binlog_do_db Binlog_ignore_db master-bin.001 79 show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 124 +127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120 slave stop; change master to master_log_pos=73; slave start; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index f27ba435729..4f6f55bce0b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2293,6 +2293,8 @@ int main(int argc, char **argv) if (!opt_noacl) udf_init(); #endif + if (opt_bootstrap) /* If running with bootstrap, do not start replication. */ + opt_skip_slave_start= 1; /* init_slave() must be called after the thread keys are created */ init_slave(); diff --git a/sql/slave.cc b/sql/slave.cc index bc9528ae2c7..aa9dd14b1c7 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1424,6 +1424,12 @@ static int count_relay_log_space(RELAY_LOG_INFO* rli) if (add_relay_log(rli,&linfo)) DBUG_RETURN(1); } while (!rli->relay_log.find_next_log(&linfo, 1)); + /* + As we have counted everything, including what may have written in a + preceding write, we must reset bytes_written, or we may count some space + twice. + */ + rli->relay_log.reset_bytes_written(); DBUG_RETURN(0); } @@ -3213,8 +3219,25 @@ Log_event* next_event(RELAY_LOG_INFO* rli) hot_log=0; // Using old binary log } } - DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE); - DBUG_ASSERT(my_b_tell(cur_log) == rli->relay_log_pos + rli->pending); +#ifndef DBUG_OFF + { + DBUG_ASSERT(my_b_tell(cur_log) >= BIN_LOG_HEADER_SIZE); + /* The next assertion sometimes (very rarely) fails, let's try to track it */ + char llbuf1[22], llbuf2[22]; + /* Merging man, please be careful with this; in 4.1, the assertion below is + replaced by + DBUG_ASSERT(my_b_tell(cur_log) == rli->event_relay_log_pos); + so you should not merge blindly (fortunately it won't build then), and + instead modify the merged code. Thanks. */ + DBUG_PRINT("info", ("Before assert, my_b_tell(cur_log)=%s \ +rli->relay_log_pos=%s rli->pending=%lu", + llstr(my_b_tell(cur_log),llbuf1), + llstr(rli->relay_log_pos,llbuf2), + rli->pending)); + DBUG_ASSERT(my_b_tell(cur_log) == rli->relay_log_pos + rli->pending); + } +#endif + /* Relay log is always in new format - if the master is 3.23, the I/O thread will convert the format for us diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 225d84f4751..697b5d8ffd6 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2250,7 +2250,7 @@ int mysql_grant (THD *thd, const char *db, List &list, if (!initialized) { send_error(&(thd->net), ER_UNKNOWN_COM_ERROR); /* purecov: tested */ - return 1; /* purecov: tested */ + DBUG_RETURN(1); /* purecov: tested */ } if (lower_case_table_names && db) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index bf4b1eb0c70..8fb82798a45 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -796,6 +796,25 @@ err: DBUG_RETURN(error); } +/* + + Kill all Binlog_dump threads which previously talked to the same slave + ("same" means with the same server id). Indeed, if the slave stops, if the + Binlog_dump thread is waiting (pthread_cond_wait) for binlog update, then it + will keep existing until a query is written to the binlog. If the master is + idle, then this could last long, and if the slave reconnects, we could have 2 + Binlog_dump threads in SHOW PROCESSLIST, until a query is written to the + binlog. To avoid this, when the slave reconnects and sends COM_BINLOG_DUMP, + the master kills any existing thread with the slave's server id (if this id is + not zero; it will be true for real slaves, but false for mysqlbinlog when it + sends COM_BINLOG_DUMP to get a remote binlog dump). + + SYNOPSIS + kill_zombie_dump_threads() + slave_server_id the slave's server id + +*/ + void kill_zombie_dump_threads(uint32 slave_server_id) { From 7fd579148dc2568187add8e3edab24bc56116b4b Mon Sep 17 00:00:00 2001 From: "miguel@hegel.(none)" <> Date: Wed, 2 Jul 2003 20:34:19 -0400 Subject: [PATCH 108/237] Fix VC++ compiler error on Windows --- mysys/thr_alarm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 2a16eeec215..2289f8208bc 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -718,7 +718,7 @@ sig_handler process_alarm(int sig __attribute__((unused))) } -bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm) +my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm) { (*alrm)= &alarm->alarmed; if (alarm_aborted) From 67b6ba21c3d9dbbdab29a254b7497c14d9f82a6d Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 3 Jul 2003 03:34:20 +0300 Subject: [PATCH 109/237] lock0lock.c: Remove outdated comment and the corresponding assertion in debug version code --- innobase/lock/lock0lock.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 397a8158bee..3f9b5316185 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -83,10 +83,6 @@ x-lock also has an explicit non-gap record x-lock. Therefore, as locks are released, we can grant locks to waiting lock requests purely by looking at the explicit lock requests in the queue. -RULE 2: Granted non-gap locks on a record are always ahead in the queue -------- -of waiting non-gap locks on a record. - RULE 3: Different transactions cannot have conflicting granted non-gap locks ------- on a record at the same time. However, they can have conflicting granted gap @@ -4271,7 +4267,6 @@ lock_rec_queue_validate( { trx_t* impl_trx; lock_t* lock; - ibool is_waiting; ut_a(rec); @@ -4332,8 +4327,6 @@ lock_rec_queue_validate( } } - is_waiting = FALSE; - lock = lock_rec_get_first(rec); while (lock) { @@ -4346,8 +4339,6 @@ lock_rec_queue_validate( } if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) { - - ut_a(!is_waiting); if (lock_get_mode(lock) == LOCK_S) { ut_a(!lock_rec_other_has_expl_req(LOCK_X, @@ -4359,7 +4350,6 @@ lock_rec_queue_validate( } else if (lock_get_wait(lock) && !lock_rec_get_gap(lock)) { - is_waiting = TRUE; ut_a(lock_rec_has_to_wait_in_queue(lock)); } From 0cdf7f39af33767fa5cd1b6bbedb14400ea3ad6c Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Thu, 3 Jul 2003 10:42:13 +0500 Subject: [PATCH 110/237] Proposed bugfix for #717 Current table is placed into read_tables set of the current join_tab->select so get_mm_parts function thinks that current table's record is read and tries to calculate WHERE condition with the fields of the record. Result of these calculations is unpredictable. Looks funny - outcome of the SELECT depends on the queries executed before. Anyway i think we should have testcase on this part of the code. --- mysql-test/r/sel000001.result | 14 ++++++++++++++ mysql-test/t/sel000001.test | 13 +++++++++++++ sql/sql_select.cc | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/sel000001.result b/mysql-test/r/sel000001.result index 28f6d3d1d5a..6b6b9b7dffc 100644 --- a/mysql-test/r/sel000001.result +++ b/mysql-test/r/sel000001.result @@ -5,3 +5,17 @@ SELECT s, id FROM t1 WHERE s = 'mouse'; s id mouse 3 drop table t1; +CREATE TABLE t1 ( +node int(11) NOT NULL default '0', +maxchild int(11) NOT NULL default '0', +PRIMARY KEY (`node`) +); +INSERT INTO t1 (node, maxchild) VALUES (4,4),(5,5),(1,244); +SELECT * FROM t1 g1, t1 g2 +WHERE g1.node <= g2.node and g2.node <= g1.maxchild and g2.node = g2.maxchild; +node maxchild node maxchild +4 4 4 4 +5 5 5 5 +1 244 4 4 +1 244 5 5 +DROP TABLE t1; diff --git a/mysql-test/t/sel000001.test b/mysql-test/t/sel000001.test index 77355f8d535..ad4af1f92fb 100644 --- a/mysql-test/t/sel000001.test +++ b/mysql-test/t/sel000001.test @@ -16,3 +16,16 @@ CREATE TABLE t1 (s CHAR(20) PRIMARY KEY, id INT); INSERT INTO t1 VALUES ('cat', 1), ('mouse', 3), ('dog', 2), ('snake', 77); SELECT s, id FROM t1 WHERE s = 'mouse'; drop table t1; + +# +#test for bug #717 +# +CREATE TABLE t1 ( + node int(11) NOT NULL default '0', + maxchild int(11) NOT NULL default '0', + PRIMARY KEY (`node`) +); +INSERT INTO t1 (node, maxchild) VALUES (4,4),(5,5),(1,244); +SELECT * FROM t1 g1, t1 g2 + WHERE g1.node <= g2.node and g2.node <= g1.maxchild and g2.node = g2.maxchild; +DROP TABLE t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 5b5972be384..bde5392d299 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2683,7 +2683,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) (select->quick && (select->quick->records >= 100L)))) ? 2 : 1; - sel->read_tables= used_tables; + sel->read_tables= used_tables & ~current_map; } if (i != join->const_tables && tab->use_quick != 2) { /* Read with cache */ From c21728f8c864c19ac462ded81c276dc08319de03 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Thu, 3 Jul 2003 11:55:36 +0300 Subject: [PATCH 111/237] Cleaner implementation if INSERT ... SELECT with same tables Tests cleanup (put drop database first in tests) --- client/mysql.cc | 14 ++++------- include/config-win.h | 1 - include/my_global.h | 7 ++++-- mysql-test/r/ctype_cp1251.result | 24 ++++++++++++++++++ mysql-test/r/drop.result | 2 -- mysql-test/r/flush.result | 2 +- mysql-test/r/grant_cache.result | 1 + mysql-test/r/innodb.result | 1 + mysql-test/r/insert_select.result | 20 +++++++++++++++ mysql-test/r/merge.result | 12 +++++++++ mysql-test/r/query_cache.result | 3 ++- mysql-test/t/ctype_cp1251-master.opt | 2 ++ mysql-test/t/ctype_cp1251.test | 17 +++++++++++++ mysql-test/t/drop.test | 2 -- mysql-test/t/flush.test | 4 +-- mysql-test/t/grant_cache.test | 5 +++- mysql-test/t/innodb.test | 2 ++ mysql-test/t/insert_select.test | 22 +++++++++++++++++ mysql-test/t/merge.test | 13 ++++++++++ mysql-test/t/query_cache.test | 3 ++- mysql-test/t/symlink.test | 25 ++++++++++--------- sql/mysql_priv.h | 11 +++++++++ sql/sql_lex.h | 2 +- sql/sql_list.h | 37 +++++++++++++++++----------- sql/sql_parse.cc | 36 +++++++++++---------------- sql/sql_yacc.yy | 10 +++++--- 26 files changed, 202 insertions(+), 76 deletions(-) create mode 100644 mysql-test/r/ctype_cp1251.result create mode 100644 mysql-test/t/ctype_cp1251-master.opt create mode 100644 mysql-test/t/ctype_cp1251.test diff --git a/client/mysql.cc b/client/mysql.cc index 171bd9cf0a8..81f4b19f7c6 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2592,14 +2592,11 @@ static void mysql_end_timer(ulong start_time,char *buff) static const char* construct_prompt() { - //erase the old prompt - if (!mysql_get_host_info(&mysql)) - return processed_prompt.ptr(); - processed_prompt.free(); - //get the date struct - time_t lclock = time(NULL); + processed_prompt.free(); // Erase the old prompt + time_t lclock = time(NULL); // Get the date struct struct tm *t = localtime(&lclock); - //parse thru the settings for the prompt + + /* parse thru the settings for the prompt */ for (char *c = current_prompt; *c ; *c++) { if (*c != PROMPT_CHAR) @@ -2608,8 +2605,7 @@ static const char* construct_prompt() { switch (*++c) { case '\0': - //stop it from going beyond if ends with % - c--; + c--; // stop it from going beyond if ends with % break; case 'c': add_int_to_prompt(++prompt_counter); diff --git a/include/config-win.h b/include/config-win.h index 096c00e4574..69020636893 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -246,7 +246,6 @@ inline double ulonglong2double(ulonglong value) #define HAVE_PERROR #define HAVE_VFPRINT -#define HAVE_CHSIZE /* System has chsize() function */ #define HAVE_RENAME /* Have rename() as function */ #define HAVE_BINARY_STREAMS /* Have "b" flag in streams */ #define HAVE_LONG_JMP /* Have long jump function */ diff --git a/include/my_global.h b/include/my_global.h index 03f4db1b5ab..673e5a22868 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -893,8 +893,11 @@ typedef union { double v; long m[2]; } doubleget_union; -#define doubleget(V,M) { ((doubleget_union *)&V)->m[0] = *((long*) M); \ - ((doubleget_union *)&V)->m[1] = *(((long*) M)+1); } +#define doubleget(V,M) \ +{ doubleget_union _tmp; \ + _tmp.m[0] = *((long*)(M)); \ + _tmp.m[1] = *(((long*) (M))+1); \ + (V) = _tmp.v; } #define doublestore(T,V) { *((long *) T) = ((doubleget_union *)&V)->m[0]; \ *(((long *) T)+1) = ((doubleget_union *)&V)->m[1]; } #define float4get(V,M) { *((long *) &(V)) = *((long*) (M)); } diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result new file mode 100644 index 00000000000..a1f860e1f83 --- /dev/null +++ b/mysql-test/r/ctype_cp1251.result @@ -0,0 +1,24 @@ +drop table if exists t1; +create table t1 (a varchar(10) not null); +insert into t1 values ("a"),("ab"),("abc"); +select * from t1; +a +a +ab +abc +select a, left(a,1) as b from t1; +a b +a a +ab a +abc a +select a, left(a,1) as b from t1 group by a; +a b +a a +ab a +abc a +SELECT DISTINCT RIGHT(a,1) from t1; +RIGHT(a,1) +a +b +c +drop table t1; diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 178c3a8cb4f..5c732aebbcc 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -1,5 +1,4 @@ drop table if exists t1; -drop table if exists t1; drop table t1; Unknown table 't1' create table t1(n int); @@ -24,7 +23,6 @@ n drop database if exists mysqltest; create database mysqltest; drop database mysqltest; -drop database if exists mysqltest; flush tables with read lock; create database mysqltest; Got one of the listed errors diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result index 7080f2b6145..8dc73e446c7 100644 --- a/mysql-test/r/flush.result +++ b/mysql-test/r/flush.result @@ -1,4 +1,5 @@ drop table if exists t1; +drop database if exists mysqltest; create temporary table t1(n int not null primary key); drop table if exists t2; create table t2(n int); @@ -11,7 +12,6 @@ drop table t2; Table 't2' was locked with a READ lock and can't be updated drop table t2; unlock tables; -drop database if exists mysqltest; create database mysqltest; create table mysqltest.t1(n int); insert into mysqltest.t1 values (23); diff --git a/mysql-test/r/grant_cache.result b/mysql-test/r/grant_cache.result index 3892765f587..fca6864cc63 100644 --- a/mysql-test/r/grant_cache.result +++ b/mysql-test/r/grant_cache.result @@ -1,4 +1,5 @@ drop table if exists test.t1,mysqltest.t1,mysqltest.t2; +drop database if exists mysqltest; reset query cache; flush status; create database if not exists mysqltest; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 465d4faf0bc..cb6c8397c5a 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1,4 +1,5 @@ drop table if exists t1,t2,t3; +drop database if exists mysqltest; create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=innodb; insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt'); select id, code, name from t1 order by id; diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index dff5d0ff3ca..c007191b562 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -566,4 +566,24 @@ a 5 5 5 +insert into t1 select * from t1,t1; +Not unique table/alias: 't1' +drop table t1,t2; +create table t1 (a int not null primary key, b char(10)); +create table t2 (a int not null, b char(10)); +insert into t1 values (1,"t1:1"),(3,"t1:3"); +insert into t2 values (2,"t2:2"), (3,"t2:3"); +insert into t1 select * from t2; +Duplicate entry '3' for key 1 +select * from t1; +a b +1 t1:1 +3 t1:3 +2 t2:2 +replace into t1 select * from t2; +select * from t1; +a b +1 t1:1 +3 t2:3 +2 t2:2 drop table t1,t2; diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index 0bffc93c284..cf39faea41b 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -596,3 +596,15 @@ AND file_code = '0000000115' LIMIT 1; table type possible_keys key key_len ref rows Extra t2 const PRIMARY,files PRIMARY 33 const,const 1 DROP TABLE IF EXISTS t1, t2; +create table t1 (x int, y int, index xy(x, y)); +create table t2 (x int, y int, index xy(x, y)); +create table t3 (x int, y int, index xy(x, y)) type=merge union=(t1,t2); +insert into t1 values(1, 2); +insert into t2 values(1, 3); +select * from t3 where x = 1 and y < 5 order by y; +x y +1 2 +1 3 +select * from t3 where x = 1 and y < 5 order by y desc; +x y +drop table t1,t2,t3; diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 6abd572b3d9..0ef0cab423b 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -3,6 +3,7 @@ flush query cache; reset query cache; flush status; drop table if exists t1,t2,t3,t11,t21, mysqltest.t1; +drop database if exists mysqltest; create table t1 (a int not null); insert into t1 values (1),(2),(3); select * from t1; @@ -357,7 +358,7 @@ show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 0 drop table t1,t2; -create database if not exists mysqltest; +create database mysqltest; create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i)); insert into mysqltest.t1 (a) values (1); select * from mysqltest.t1 where i is null; diff --git a/mysql-test/t/ctype_cp1251-master.opt b/mysql-test/t/ctype_cp1251-master.opt new file mode 100644 index 00000000000..af089d9f176 --- /dev/null +++ b/mysql-test/t/ctype_cp1251-master.opt @@ -0,0 +1,2 @@ +--default-character-set=cp1251 --new + diff --git a/mysql-test/t/ctype_cp1251.test b/mysql-test/t/ctype_cp1251.test new file mode 100644 index 00000000000..fffade35389 --- /dev/null +++ b/mysql-test/t/ctype_cp1251.test @@ -0,0 +1,17 @@ +# Test of charset cp1251 + +--disable_warnings +drop table if exists t1; +--enable_warnings + +# +# Test problem with LEFT() (Bug #514) +# + +create table t1 (a varchar(10) not null); +insert into t1 values ("a"),("ab"),("abc"); +select * from t1; +select a, left(a,1) as b from t1; +select a, left(a,1) as b from t1 group by a; +SELECT DISTINCT RIGHT(a,1) from t1; +drop table t1; diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test index c92f2b1f3b9..2f3fa99bac0 100644 --- a/mysql-test/t/drop.test +++ b/mysql-test/t/drop.test @@ -1,5 +1,4 @@ drop table if exists t1; -drop table if exists t1; --error 1051; drop table t1; create table t1(n int); @@ -26,7 +25,6 @@ create database mysqltest; drop database mysqltest; # test drop/create database and FLUSH TABLES WITH READ LOCK -drop database if exists mysqltest; flush tables with read lock; --error 1209,1223; create database mysqltest; diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test index 540aa4235cc..7754fc2e197 100644 --- a/mysql-test/t/flush.test +++ b/mysql-test/t/flush.test @@ -10,6 +10,8 @@ connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; drop table if exists t1; +drop database if exists mysqltest; + create temporary table t1(n int not null primary key); drop table if exists t2; create table t2(n int); @@ -44,7 +46,6 @@ reap; #test if drop database will wait until we release the global read lock connection con1; -drop database if exists mysqltest; create database mysqltest; create table mysqltest.t1(n int); insert into mysqltest.t1 values (23); @@ -66,4 +67,3 @@ connection con2; insert into t1 values (345); select * from t1; drop table t1; - diff --git a/mysql-test/t/grant_cache.test b/mysql-test/t/grant_cache.test index 7dfbb3b8d83..95989d1ee99 100644 --- a/mysql-test/t/grant_cache.test +++ b/mysql-test/t/grant_cache.test @@ -1,9 +1,12 @@ -- source include/have_query_cache.inc +drop table if exists test.t1,mysqltest.t1,mysqltest.t2; +drop database if exists mysqltest; + # # Test grants with query cache # -drop table if exists test.t1,mysqltest.t1,mysqltest.t2; + reset query cache; flush status; connect (root,localhost,root,,test,$MASTER_MYPORT,master.sock); diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index cf203d87c8b..509cae9c1dc 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -5,6 +5,8 @@ # drop table if exists t1,t2,t3; +drop database if exists mysqltest; + create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=innodb; insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt'); diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index 5c7fc57262b..d115e9c1af6 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -85,6 +85,11 @@ let $VERSION=`select version()`; show binlog events; drop table t1, t2; drop table if exists t1, t2; + +# +# Test of insert ... select from same table +# + create table t1 (a int not null); create table t2 (a int not null); insert into t1 values (1); @@ -99,4 +104,21 @@ insert into t2 select * from t1 as t2; select * from t1; insert into t1 select t2.a from t1,t2; select * from t1; +--error 1066 +insert into t1 select * from t1,t1; +drop table t1,t2; + +# +# test replace ... select +# + +create table t1 (a int not null primary key, b char(10)); +create table t2 (a int not null, b char(10)); +insert into t1 values (1,"t1:1"),(3,"t1:3"); +insert into t2 values (2,"t2:2"), (3,"t2:3"); +--error 1062 +insert into t1 select * from t2; +select * from t1; +replace into t1 select * from t2; +select * from t1; drop table t1,t2; diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test index e2cd8b57b7e..b625e780f1f 100644 --- a/mysql-test/t/merge.test +++ b/mysql-test/t/merge.test @@ -237,3 +237,16 @@ EXPLAIN SELECT * FROM t2 WHERE fileset_id = 2 AND file_code = '0000000115' LIMIT 1; DROP TABLE IF EXISTS t1, t2; +# +# Test of ORDER BY DESC on key (Bug #515) +# + +create table t1 (x int, y int, index xy(x, y)); +create table t2 (x int, y int, index xy(x, y)); +create table t3 (x int, y int, index xy(x, y)) type=merge union=(t1,t2); +insert into t1 values(1, 2); +insert into t2 values(1, 3); +select * from t3 where x = 1 and y < 5 order by y; +# Bug is that followng query returns empty set while it must be same as above +select * from t3 where x = 1 and y < 5 order by y desc; +drop table t1,t2,t3; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index f0f3063c00d..fe258b2c7e1 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -11,6 +11,7 @@ flush query cache; # This crashed in some versions reset query cache; flush status; drop table if exists t1,t2,t3,t11,t21, mysqltest.t1; +drop database if exists mysqltest; # # First simple test @@ -241,7 +242,7 @@ drop table t1,t2; # # noncachable ODBC work around (and prepare cache for drop database) # -create database if not exists mysqltest; +create database mysqltest; create table mysqltest.t1 (i int not null auto_increment, a int, primary key (i)); insert into mysqltest.t1 (a) values (1); select * from mysqltest.t1 where i is null; diff --git a/mysql-test/t/symlink.test b/mysql-test/t/symlink.test index 586761921b8..d8bba12b645 100644 --- a/mysql-test/t/symlink.test +++ b/mysql-test/t/symlink.test @@ -3,10 +3,12 @@ disable_query_log; show variables like "have_symlink"; enable_query_log; +drop table if exists t1,t2,t7,t8,t9; +drop database if exists mysqltest; + # # First create little data to play with # -drop table if exists t1,t2,t7,t8,t9; create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)); create table t2 (a int not null auto_increment, b char(16) not null, primary key (a)); insert into t1 (b) values ("test"),("test1"),("test2"),("test3"); @@ -64,26 +66,25 @@ create table t1 (a int not null auto_increment, b char(16) not null, primary key # Check that we cannot link over a table from another database. -drop database if exists test_mysqltest; -create database test_mysqltest; +create database mysqltest; --error 1,1 -create table test_mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="/this-dir-does-not-exist"; +create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="/this-dir-does-not-exist"; --error 1103,1103 -create table test_mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="not-hard-path"; +create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="not-hard-path"; --error 1,1 -eval create table test_mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="$MYSQL_TEST_DIR/var/run"; +eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam index directory="$MYSQL_TEST_DIR/var/run"; --error 1,1 -eval create table test_mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam data directory="$MYSQL_TEST_DIR/var/tmp"; +eval create table mysqltest.t9 (a int not null auto_increment, b char(16) not null, primary key (a)) type=myisam data directory="$MYSQL_TEST_DIR/var/tmp"; enable_query_log; -# Check moving table t9 from default database to test_mysqltest; +# Check moving table t9 from default database to mysqltest; # In this case the symlinks should be removed. -alter table t9 rename test_mysqltest.t9; -select count(*) from test_mysqltest.t9; -show create table test_mysqltest.t9; -drop database test_mysqltest; +alter table t9 rename mysqltest.t9; +select count(*) from mysqltest.t9; +show create table mysqltest.t9; +drop database mysqltest; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 702db98748a..14680306e5d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -253,6 +253,17 @@ typedef struct st_sql_list { next= next_ptr; *next=0; } + inline void save_and_clear(struct st_sql_list *save) + { + *save= *this; + empty(); + } + inline void push_front(struct st_sql_list *save) + { + *save->next= first; /* link current list last */ + first= save->first; + elements+= save->elements; + } } SQL_LIST; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 0618f04a79b..ab78555262f 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -153,7 +153,7 @@ typedef struct st_lex List *insert_list,field_list,value_list; List many_values; List var_list; - SQL_LIST proc_list, auxilliary_table_list; + SQL_LIST proc_list, auxilliary_table_list, save_list; TYPELIB *interval; create_field *last_field; char* savepoint_name; // Transaction savepoint id diff --git a/sql/sql_list.h b/sql/sql_list.h index 15bbb5c5ec7..102fbe8eb93 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -15,12 +15,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* mysql standard open memoryallocator */ - #ifdef __GNUC__ #pragma interface /* gcc class implementation */ #endif +/* mysql standard class memoryallocator */ class Sql_alloc { @@ -38,14 +37,15 @@ public: }; + /* -** basic single linked list -** Used for item and item_buffs. -** All list ends with a pointer to the 'end_of_list' element, which -** data pointer is a null pointer and the next pointer points to itself. -** This makes it very fast to traverse lists as we don't have to -** test for a specialend condition for list that can't contain a null -** pointer. + Basic single linked list + Used for item and item_buffs. + All list ends with a pointer to the 'end_of_list' element, which + data pointer is a null pointer and the next pointer points to itself. + This makes it very fast to traverse lists as we don't have to + test for a specialend condition for list that can't contain a null + pointer. */ class list_node :public Sql_alloc @@ -65,9 +65,11 @@ public: friend class base_list_iterator; }; + extern list_node end_of_list; -class base_list :public Sql_alloc { +class base_list :public Sql_alloc +{ protected: list_node *first,**last; @@ -243,6 +245,7 @@ public: inline T** ref(void) { return (T**) base_list_iterator::ref(); } }; + template class List_iterator_fast :public base_list_iterator { protected: @@ -260,11 +263,12 @@ public: /* -** A simple intrusive list which automaticly removes element from list -** on delete (for THD element) + A simple intrusive list which automaticly removes element from list + on delete (for THD element) */ -struct ilink { +struct ilink +{ struct ilink **prev,*next; static void *operator new(size_t size) { @@ -289,9 +293,11 @@ struct ilink { virtual ~ilink() { unlink(); } /*lint -e1740 */ }; + template class I_List_iterator; -class base_ilist { +class base_ilist +{ public: struct ilink *first,last; base_ilist() { first= &last; last.prev= &first; } @@ -339,7 +345,8 @@ public: template -class I_List :private base_ilist { +class I_List :private base_ilist +{ public: I_List() :base_ilist() {} inline bool is_empty() { return base_ilist::is_empty(); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4031ffabf97..fef74262d22 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1972,6 +1972,11 @@ mysql_execute_command(void) if (thd->select_limit < select_lex->select_limit) thd->select_limit= HA_POS_ERROR; // No limit + if (check_dup(tables->db, tables->real_name, tables->next)) + { + /* Using same table for INSERT and SELECT */ + select_lex->options |= OPTION_BUFFER_RESULT; + } { /* TODO: Delete the following loop when locks is set by sql_yacc */ TABLE_LIST *table; @@ -2478,9 +2483,11 @@ mysql_execute_command(void) res = mysql_ha_close(thd, tables); break; case SQLCOM_HA_READ: - /* there is no need to check for table permissions here, because - if a user has no permissions to read a table, he won't be - able to open it (with SQLCOM_HA_OPEN) in the first place. */ + /* + There is no need to check for table permissions here, because + if a user has no permissions to read a table, he won't be + able to open it (with SQLCOM_HA_OPEN) in the first place. + */ if (check_db_used(thd,tables)) goto error; res = mysql_ha_read(thd, tables, lex->ha_read_mode, lex->backup_dir, @@ -2898,10 +2905,7 @@ void mysql_init_multi_delete(LEX *lex) lex->sql_command = SQLCOM_DELETE_MULTI; mysql_init_select(lex); lex->select->select_limit=lex->thd->select_limit=HA_POS_ERROR; - lex->auxilliary_table_list=lex->select_lex.table_list; - lex->select->table_list.elements=0; - lex->select->table_list.first=0; - lex->select->table_list.next= (byte**) &(lex->select->table_list.first); + lex->select->table_list.save_and_clear(&lex->auxilliary_table_list); } @@ -3386,22 +3390,10 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, tables ; tables=tables->next) { - if (ptr->db_length == tables->db_length && !memcmp(ptr->db, tables->db, ptr->db_length)) + if (!strcmp(alias_str,tables->alias) && !strcmp(ptr->db, tables->db)) { - if ((thd->lex.sql_command & (SQLCOM_INSERT_SELECT | SQLCOM_REPLACE_SELECT)) - && (tables->lock_type & (TL_WRITE_CONCURRENT_INSERT | - TL_WRITE_LOW_PRIORITY | TL_WRITE_DELAYED | - TL_WRITE))) - { - if (ptr->real_name_length == tables->real_name_length && - !memcmp(ptr->real_name, tables->real_name,ptr->real_name_length)) - thd->lex.select->options |= OPTION_BUFFER_RESULT; - } - else if (!strcmp(alias_str,tables->alias)) - { - net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */ - DBUG_RETURN(0); /* purecov: tested */ - } + net_printf(&thd->net,ER_NONUNIQ_TABLE,alias_str); /* purecov: tested */ + DBUG_RETURN(0); /* purecov: tested */ } } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index cf580b3f3df..94beff074c5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -824,13 +824,15 @@ create_select: { LEX *lex=Lex; lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; - switch(lex->sql_command) { - case SQLCOM_INSERT: lex->sql_command=SQLCOM_INSERT_SELECT; break; - case SQLCOM_REPLACE: lex->sql_command=SQLCOM_REPLACE_SELECT; break; - } + if (lex->sql_command == SQLCOM_INSERT) + lex->sql_command= SQLCOM_INSERT_SELECT; + else if (lex->sql_command == SQLCOM_REPLACE) + lex->sql_command= SQLCOM_REPLACE_SELECT; + lex->select->table_list.save_and_clear(&lex->save_list); mysql_init_select(lex); } select_options select_item_list opt_select_from + { Lex->select->table_list.push_front(&Lex->save_list); } ; opt_as: From f0a5bc00ccec61b0119d0ecd1d3de3f3162a5b1b Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Thu, 3 Jul 2003 12:30:52 +0300 Subject: [PATCH 112/237] Fixed wrong usage of libvio.a (Bug #556) --- vio/Makefile.am | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/vio/Makefile.am b/vio/Makefile.am index b53f3be9f91..ab8fac51ee7 100644 --- a/vio/Makefile.am +++ b/vio/Makefile.am @@ -14,21 +14,24 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -INCLUDES = -I$(srcdir)/../include -I../include $(openssl_includes) -LDADD = @CLIENT_EXTRA_LDFLAGS@ libvio.a $(openssl_libs) -pkglib_LIBRARIES = libvio.a +INCLUDES= -I$(srcdir)/../include -I../include $(openssl_includes) +LDADD= @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs) +pkglib_LIBRARIES= libvio.a noinst_PROGRAMS = test-ssl test-sslserver test-sslclient -noinst_HEADERS = -test_ssl_SOURCES = test-ssl.c -test_ssl_LDADD = @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a ../mysys/libmysys.a \ - ../strings/libmystrings.a libvio.a $(openssl_libs) -test_sslserver_SOURCES = test-sslserver.c -test_sslserver_LDADD = @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a ../mysys/libmysys.a \ - ../strings/libmystrings.a libvio.a $(openssl_libs) -test_sslclient_SOURCES = test-sslclient.c -test_sslclient_LDADD = @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a ../mysys/libmysys.a \ - ../strings/libmystrings.a libvio.a $(openssl_libs) -libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c +noinst_HEADERS= +test_ssl_SOURCES= test-ssl.c +test_ssl_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \ + ../mysys/libmysys.a ../strings/libmystrings.a \ + $(openssl_libs) +test_sslserver_SOURCES= test-sslserver.c +test_sslserver_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \ + ../mysys/libmysys.a ../strings/libmystrings.a \ + $(openssl_libs) +test_sslclient_SOURCES= test-sslclient.c +test_sslclient_LDADD= @CLIENT_EXTRA_LDFLAGS@ ../dbug/libdbug.a libvio.a \ + ../mysys/libmysys.a ../strings/libmystrings.a \ + $(openssl_libs) +libvio_a_SOURCES= vio.c viosocket.c viossl.c viosslfactories.c # Don't update the files from bitkeeper %::SCCS/s.% From 95d6b7a5ea235c9ac29264598d6672a7031cc4ee Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Thu, 3 Jul 2003 16:48:47 +0500 Subject: [PATCH 113/237] Testcase for #628 --- mysql-test/r/func_misc.result | 3 +++ mysql-test/t/func_misc.test | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 8d05adcc1ba..d51bea020ed 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -13,3 +13,6 @@ NULL 255.255.1.255 0.0.1.255 select length(format('nan', 2)) > 0; length(format('nan', 2)) > 0 1 +select concat("$",format(2500,2)); +concat("$",format(2500,2)) +$2,500.00 diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index be64c170fa1..d15c26279ec 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -12,3 +12,8 @@ select inet_ntoa(1099511627775),inet_ntoa(4294902271),inet_ntoa(511); # Test for core dump with nan # select length(format('nan', 2)) > 0; + +# +# Test for bug #628 +# +select concat("$",format(2500,2)); From 1bd7127208de1a87de55e4fc8824065d35640349 Mon Sep 17 00:00:00 2001 From: "peter@mysql.com" <> Date: Thu, 3 Jul 2003 16:41:46 +0400 Subject: [PATCH 114/237] New Sample config file. The changes for actual loads and memory sizes are to be done after text and format are improved. --- support-files/my-innodb-heavy-4G.cnf.sh | 469 ++++++++++++++++++++++++ 1 file changed, 469 insertions(+) create mode 100644 support-files/my-innodb-heavy-4G.cnf.sh diff --git a/support-files/my-innodb-heavy-4G.cnf.sh b/support-files/my-innodb-heavy-4G.cnf.sh new file mode 100644 index 00000000000..b8c49bbf0bc --- /dev/null +++ b/support-files/my-innodb-heavy-4G.cnf.sh @@ -0,0 +1,469 @@ +#BEGIN CONFIG INFO +#DESCR: 4G,Innodb only,ACID, Few Connections heavy queries +#TYPE: SYSTEM +#END CONFIG INFO + +# This is example config file for systems with 4G of memory running mostly MySQL +# using MyISAM only tables and running complex queries with few connections +# + + + + +# +# You can copy this file to +# /etc/my.cnf to set global options, +# mysql-data-dir/my.cnf to set server-specific options (in this +# installation this directory is @localstatedir@) or +# ~/.my.cnf to set user-specific options. +# +# One can in this file use all long options that the program supports. +# If you want to know which options a program support, run the program +# with --help option. + + + +# The following options will be passed to all MySQL clients +# But note, only client programs shipped by MySQL are guarantied to read it +# If you wish your software to read this section you would need to specify +# it as an option during MySQL client library initialization +[client] +#password = your_password +port = @MYSQL_TCP_PORT@ +socket = @MYSQL_UNIX_ADDR@ + +# ********** Here follows entries for some specific programs + +# The MySQL server +[mysqld] +# generic configuration options + +port = @MYSQL_TCP_PORT@ +socket = @MYSQL_UNIX_ADDR@ + + +# Back Log is a number of connection OS can keep in queue, before MySQL +# connection manager thread has processed them. If you have very intensive +# connection rate and experience "connection refused" errors you might need +# to increase this value +back_log = 50 + + +# Don't listen on a TCP/IP port at all. This can be a security enhancement, +# if all processes that need to connect to mysqld run on the same host. +# All interaction with mysqld must be made via Unix sockets or named pipes. +# Note that using this option without enabling named pipes on Windows +# (via the "enable-named-pipe" option) will render mysqld useless! +#skip-networking + +# Maximum amount of concurrent sessions MySQL server will allow +# One of these connections will be reserved for user with SUPER privelege +# to allow administrator to login even if server is overloaded. +max_connections = 100 + + +# Maximum amount of errors allowed per host. If this limit is reached +# host will be blocked from connection MySQL server until "flush hosts" +# is run or server restart. Invalid passwords as any other errors at +# connect phase results in increasing this value. See +# Aborted_Connects status variable for global counter. +max_connect_errors = 10 + + +# Amount of tables server can keep open at the time. Each table +# may require up to 2 file handlers (for MERGE tables even more) +# so make sure to have amount of open files allowed at least 4096 +# see open-files-limit in [mysqld_safe] +table_cache = 2048 + +# Do not use file level locking. Enabled file locking give performance +# hit, so use it only in case you have serveral database instances +# running on the same files (note some restrictions still apply!) +# or if you use other software relaying on locking MyISAM tables +# on file level +#enable-locking + +# This packets limits maximum size of BLOB server can handle +# as well as maximum query size server can process +# enlarged dynamically, for each connection +max_allowed_packet = 16M + +# Binary log cache is used for logging transactions to binary log +# all statements from transactions are buffered in binary log cache +# and wrote to the binary log at once on commit +# if transaction is large than this value disk temporary file is used. +# This buffer is allocated per connection on first update statement +# in transaction +binlog_cache_size = 1M + + +# Maximum allowed size for single HEAP (in memory) table +# This option is protection from accidential creation of the HEAP +# table which would take all the memory resources +max_heap_table_size=64M + + +# Sort buffer used to perform sorts for some of ORDER BY and +# GROUP BY queries. If sorted data does not fit into sort buffer +# Disk based merge sort is used - See sort_merge_passes. +# Allocated per thread if sort is needed +sort_buffer_size = 8M + +# This buffer is used for optimization of full joins (joins without indexes) +# Such joins are very bad for performance in most cases anyway, but having +# this variable large reduces performance impact. +# see select_full_join status variable for full joins count +# Allocated per thread if full join is found +join_buffer_size=8M + + +# Cache threads on disconnect instead of destroying them +# thread cache allows to greatly reduce amount of thread +# creations needed if you have a lot of connections +thread_cache = 8 + + +# Try number of CPU's*(2..4) for thread_concurrency +# This value makes sense only on few systems (as Solaris) +# which support thread_concurrency() setting +thread_concurrency = 8 + + +# Query cache is used to cache SELECT results and later return +# them without actual query execution for exactly the same query +# Having query cache enabled may give great benefit if your have +# typical queries and rarely changed tabled +# see Qcache_lowmem_prunes status variable to check if current +# value is enough for your load +# Note: In case your table change all the time or you never have +# textually same queries query cache maay bring slowdown +# instead of performance improvement +query_cache_size = 64M + +# Cache only result sets which are smaller than this limit +# This setting is protection of very large result set overwriting +# all queries in query cache +query_cache_limit = 2M + +# Minimum word length to be indexed by full text search index +# you might wish to decrease it if you need to search on shorter words +ft_min_word_len = 4 + +# If your system supports memlock() function you might use this option +# while running MySQL to keep it locking in memory, avoid potential +# swapping out in case of high memory pressure. Good for performance. +#memlock + +# Table type which is used by default, if not specified by CREATE TABLE +# it affects only tables explicitly created by user. +default_table_type = MYISAM + +# Thread stack size to use. This amount of memory is always reserved at +# connection time. MySQL itself usually needs no more than 64K of memory, +# while if you use your own stack hungry UDF functions or OS requires more +# stack for some operations, you might need to set it higher +thread_stack = 192K + +# Set default transaction isolation level. Levels available are: +# READ-UNCOMMITED, READ-COMMITED, REPEATABLE-READ, SERIALIZABLE +transaction_isolation = REPEATABLE-READ + +# Maximum size for internal in memory temporary table. If table +# grows larger it is automatically converted to disk based table +# This limitaion is for single table. There can be many of them. +tmp_table_size = 64M + +# binary logging is required for acting MASTER in replication +# You also need binary log if you need ability to do point +# in time recovery from your latest backup +log_bin + +# If you're using chaining replication A->B->C you might wish to +# turn on this option on server B. It makes updates done by +# slave thread also logged in binary log. Normally they are not +#log_slave_updates + + +# Full query log. Every query (even with incorrect syntax) server gets goes here. +# Useful for debugging. Normally is disabled in production +#log + +# If you have any problems with MySQL server you might enable Warnings logging and +# examine error log for possible explanations. +#log_warnings + +# Log slow queries. Slow queries are queries which take more than defined amount of time +# or which do not use indexes well, if log_long_format is enabled +# It is notmally good idea to have this on if you frequently add new queries to the system +log_slow_queries + + +# All queries taking more than this amount of time will be trated as slow. Do not use value 1 +# here as this will result even in very fast queries logged sometimes, as MySQL measures time with +# second accuracy only. +long_query_time = 2 + +# Log more information in slow query log. Normally it is good to have this on. +# It results in logging of queries not using indexes additionally to long running queries. +log_long_format + + + +# Temporary directory is used by MySQL for storing temporary files, for example +# used to do disk based large sorts, as well as for internal and explicit +# temporary tables. +# It might be good to set it to swapfs/tmpfs filesystem if you do not have very +# large temporary files created or set it to dedicated disk +# You can specify several paths here spliting them by ";" they will be used in +# round-robin fashion +#tmpdir = /tmp + + +#*** Replication related settings + + +# This value is required both for master ans slave +# If you have single master it is typical to use value 1 for it +# required unique id between 1 and 2^32 - 1 +# defaults to 1 if master-host is not set +# but will not function as a master if omitted +server-id = 1 + + +# To configure this server as Replication Slave you will need +# to set its server_id to some unique value, different from Master +# and all slaves in the group. +# You also can disable log-bin as logs are not required (while recomended) +# for slaves +# +# +# The recomended way to set MASTER settings for the slave are: +# Use the CHANGE MASTER TO command (fully described in our manual) - +# the syntax is: +# +# CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=, +# MASTER_USER=, MASTER_PASSWORD= ; +# +# where you replace , , by quoted strings and +# by the master's port number (3306 by default). +# +# Example: +# +# CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306, +# MASTER_USER='joe', MASTER_PASSWORD='secret'; +# +# However if you need to replicate slave configuration over several boxes +# you can use old approach: +# +# Set the variables below. However, in case you choose this method, then +# start replication for the first time (even unsuccessfully, for example +# if you mistyped the password in master-password and the slave fails to +# connect), the slave will create a master.info file, and any later +# change in this file to the variables' values below will be ignored and +# overridden by the content of the master.info file, unless you shutdown +# the slave server, delete master.info and restart the slaver server. +# For that reason, you may want to leave the lines below untouched +# (commented) and instead use CHANGE MASTER TO (see above) +# +# +# The replication master for this slave - required +#master-host = +# +# The username the slave will use for authentication when connecting +# to the master - required +#master-user = +# +# The password the slave will authenticate with when connecting to +# the master - required +#master-password = +# +# The port the master is listening on. +# optional - defaults to 3306 +#master-port = + +# Make Slave ReadOnly. Only user with SUPER privelege and slave +# thread will be able to modify it. You might use it to ensure +# no applications will accidently modify slave instead of master +#read_only + + + +#*** MyISAM Specific options + + +# Size of Key Buffer, used to cache index blocks for MyISAM tables +# Do not set it larger than 30% of available memory, as some memory +# is required by OS to cache rows. +# Even if you're not using MyISAM tables still set it to 8-64M +# as it will be used for internal temporary disk tables. +key_buffer_size = 32M + +# Size of buffer used for doing full table scans for MyISAM tables +# allocated per thread, as full scan is needed +read_buffer_size = 2M + +# Buffer is used for caching the rows while doing Sorts +# Allocated per thread, then needed +read_rnd_buffer_size = 16M + +# The bulk insert tree is used for optimization of index modification +# for bulk inserts (hundreds+ values) and LOAD DATA INFILE +# Do not set larger than key_buffer_size for optimal performance +# This buffer is allocated than bulk insert is detected +bulk_insert_buffer_size = 64M + + +# This buffer is allocated than MySQL needs to rebuild the Index, +# in REPAIR, OPTIMZE, ALTER table statements as well as in +# LOAD DATA INFILE to empty table +# it is allocated per thread so be careful with large settings. +myisam_sort_buffer_size = 128M + +# Maximum size of temporary (sort) file index rebuild can use. +# If sort is estimated to take larger amount of space, mush slower +# (keycache) index rebuild method will be used +myisam_max_sort_file_size = 10G + +# Use sort method in case the difference between sort file and +# Table index file is estimated to be less than this value +myisam_max_extra_sort_file_size = 10G + +# If table has more than one index MyISAM can use more than one thread +# to repair them in parallel. It makes sense if you have multiple of +# CPUs and planty of memory. +myisam_repair_threads = 1 + +# Automatically check and repair not properly closed MyISAM tables +myisam_recover + + + +#*** BDB Specific options + +# Use this option if you have BDB tables enabled but you do not plan to use them +skip-bdb + + +#*** INNODB Specific options + +# Use this option if you have INNODB tables enabled but you do not plan to use them +#skip-innodb + +# Additional memory pool is used by Innodb to store metadata information. +# If Innodb needs more memory for this purpose to allocate it from OS +# As it is fast enough on most recent OS you normally do not need to set it higher +# SHOW INNODB STATUS will show current amount of it in use +innodb_additional_mem_pool_size = 16M + +# Innodb, unlike MyISAM uses bufferpool to cache both indexes and row data +# so you would normally wish to have it large up to 50-70% of your memory size +# Note on 32bit systems you might be limited to 2-3.5G of user level memory +# per process so do not set it too high. +innodb_buffer_pool_size = 2G + +# Innodb stores data in one or several files forming tablespace. If you have +# single logical drive for your data, single autoextending file would be good enough +# In other case single file per device is often good choice. +# You may setup Innodb to use Raw disk partitions as well. Refer to the manual. +innodb_data_file_path = ibdata1:10M:autoextend + + +# Set this option if you would like Innodb tablespace files to be stored in other +# location. Default is MySQL datadir. +#innodb_data_home_dir + +# Number of IO threads to use for async IO operations. This value is hardcoded to +# 4 on Unix +innodb_file_io_threads = 4 + + +# If you run into Innodb tablespace corruption, setting this to nonzero value will +# likely help you to dump your tables. Start from value 1 and increase it until +# you're able to dump the table successfully. +#innodb_force_recovery=1 + +# Number of threads allowed inside of Innodb kernel. Best setting highly depends +# on the application, hardware as well as OS scheduler properties +# Too high value may lead to thread thrashing +innodb_thread_concurrency = 16 + + +# If set to 1 Innodb will flush(fsync) logs to the disk at each transaction commit +# which offers full ACID behavior, however if you can afford few last commited transaction +# lost you can set this value to 2 or 0. Innodb will anyway flush the log file once +# per second. 0 - do not flush file at all. 2 - flush it to OS buffers but not to the disk. +innodb_flush_log_at_trx_commit = 1 + + +# Innodb uses fast shutdown by default. However you can disable it to make Innodb to do +# purge and Insert buffer merge on shutdown. It may increase shutdown time a lot but +# Innodb will have not need to do it after next startup +#innodb_fast_shutdown + +# Buffer Innodb shall use for buffering log data. As soon as it is full Innodb +# will have to flush it. As it is flushed once per second anyway even with +# long transactions it does not make sense to have it very large. +innodb_log_buffer_size = 8M + +# Size of log file in group. You shall set combined size of log files large 25%-100% of +# your buffer pool size to avoid not needed buffer pool flush activity on log file +# overwrite. Note however larger logfile size will increase time needed for recovery +# process. +innodb_log_file_size = 256M + +# Total number of files in the log group. Value 2-3 is usually good enough. +innodb_log_files_in_group = 3 + +# Location for Innodb log files. Default is MySQL datadir. You may wish to +# point it to dedicated hard drive or RAID1 volume for improved performance +#innodb_log_group_home_dir + +# Maximum allowed Percentage of dirty pages in Innodb buffer pool. +# If it is reached Innodb will start flushing them agressively not to run +# out of clean pages at all. This is a soft limit, not guarantied to be held. +innodb_max_dirty_pages_pct = 90 + + +# Set flush method Innodb will use for Log. Tablespace always uses doublewrite flush logic. +#innodb_flush_method + +# How long Innodb transaction shall wait for lock to be granted before giving up. +# This value does not correspond to deadlock resolution. Innodb will detect Deadlock +# as soon as it is formed. +innodb_lock_wait_timeout = 120 + + + +[mysqldump] +# Do not buffer whole result set in memory before writing it to file +# required for dumping very large tables +quick + +max_allowed_packet = 16M + +[mysql] +no-auto-rehash + +# Remove the next comment character if you are not familiar with SQL +#safe-updates + +[isamchk] +key_buffer = 512M +sort_buffer_size = 512M +read_buffer = 8M +write_buffer = 8M + +[myisamchk] +key_buffer = 512M +sort_buffer_size = 512M +read_buffer = 8M +write_buffer = 8M + +[mysqlhotcopy] +interactive-timeout + +[mysqld_safe] +# Increase amount of open files allowed per process +# Warning: Make sure you have global system limit high enough +# The high value is required for large number of opened tables +open-files-limit = 8192 From 726fca05f773a201dbfba86001d039422944d7da Mon Sep 17 00:00:00 2001 From: "ram@mysql.r18.ru" <> Date: Thu, 3 Jul 2003 18:21:59 +0500 Subject: [PATCH 115/237] Fix and test-case for the bug #775: SELECT misses rows in indexed HEAP table columns. --- heap/hp_open.c | 9 ++++++--- mysql-test/r/heap.result | 14 ++++++++++++++ mysql-test/t/heap.test | 9 +++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/heap/hp_open.c b/heap/hp_open.c index 1bb28e5ffdf..ec8b5fea904 100644 --- a/heap/hp_open.c +++ b/heap/hp_open.c @@ -46,9 +46,12 @@ HP_INFO *heap_open(const char *name, int mode, uint keys, HP_KEYDEF *keydef, for (j=length=0 ; j < keydef[i].keysegs; j++) { length+=keydef[i].seg[j].length; - if (keydef[i].seg[j].null_bit && - !(keydef[i].flag & HA_NULL_ARE_EQUAL)) - keydef[i].flag |= HA_NULL_PART_KEY; + if (keydef[i].seg[j].null_bit) + { + length++; + if (!(keydef[i].flag & HA_NULL_ARE_EQUAL)) + keydef[i].flag |= HA_NULL_PART_KEY; + } } keydef[i].length=length; if (length > max_length) diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index a04ddf3f302..bdf7dc225f3 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -197,6 +197,20 @@ a b INSERT INTO t1 VALUES (1,3); Duplicate entry '3' for key 1 DROP TABLE t1; +CREATE TABLE t1 ( +a int default NULL, +key a (a) +) TYPE=HEAP; +INSERT INTO t1 VALUES (10), (10), (10); +EXPLAIN SELECT * FROM t1 WHERE a=10; +table type possible_keys key key_len ref rows Extra +t1 ref a a 5 const 10 Using where +SELECT * FROM t1 WHERE a=10; +a +10 +10 +10 +DROP TABLE t1; CREATE TABLE t1 (a int not null, primary key(a)) type=heap; INSERT into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11); DELETE from t1 where a < 100; diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test index d1e647ae182..b2de58ca083 100644 --- a/mysql-test/t/heap.test +++ b/mysql-test/t/heap.test @@ -129,6 +129,15 @@ SELECT * FROM t1 WHERE b<=>NULL; INSERT INTO t1 VALUES (1,3); DROP TABLE t1; +CREATE TABLE t1 ( + a int default NULL, + key a (a) +) TYPE=HEAP; +INSERT INTO t1 VALUES (10), (10), (10); +EXPLAIN SELECT * FROM t1 WHERE a=10; +SELECT * FROM t1 WHERE a=10; +DROP TABLE t1; + # # Test when deleting all rows # From 7df3fd08c13418671c743fc45971fa218ae823e9 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Thu, 3 Jul 2003 19:01:01 +0500 Subject: [PATCH 116/237] Test case for #570 added --- mysql-test/r/alias.result | 11 +++++++++++ mysql-test/t/alias.test | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/mysql-test/r/alias.result b/mysql-test/r/alias.result index 3954c2d0170..55397705bdf 100644 --- a/mysql-test/r/alias.result +++ b/mysql-test/r/alias.result @@ -59,3 +59,14 @@ SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA', Kundentyp kategorie Privat (Private Nutzung) Mobilfunk drop table t1; +CREATE TABLE t1 ( +AUFNR varchar(12) NOT NULL default '', +PLNFL varchar(6) NOT NULL default '', +VORNR varchar(4) NOT NULL default '', +xstatus_vor smallint(5) unsigned NOT NULL default '0', +); +INSERT INTO t1 VALUES ('40004712','000001','0010',9); +INSERT INTO t1 VALUES ('40004712','000001','0020',0); +UPDATE t1 SET t1.xstatus_vor = Greatest(t1.xstatus_vor,1) WHERE t1.aufnr = +"40004712" AND t1.plnfl = "000001" AND t1.vornr > "0010" ORDER BY t1.vornr +ASC LIMIT 1; diff --git a/mysql-test/t/alias.test b/mysql-test/t/alias.test index 5c6813d93aa..0dafc62430e 100644 --- a/mysql-test/t/alias.test +++ b/mysql-test/t/alias.test @@ -62,3 +62,22 @@ INSERT INTO t1 VALUES (3359362,406,3359362,'Mustermann Musterfrau',7001,'2000-05 SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA','V','VA',''), 'Privat (Private Nutzung)','Privat (Private Nutzung) Sitz im Ausland','Privat (geschaeftliche Nutzung)','Privat (geschaeftliche Nutzung) Sitz im Ausland','Firma (Kapitalgesellschaft)','Firma (Kapitalgesellschaft) Sitz im Ausland','Firma (Personengesellschaft)','Firma (Personengesellschaft) Sitz im Ausland','oeff. rechtl. Koerperschaft','oeff. rechtl. Koerperschaft Sitz im Ausland','Eingetragener Verein','Eingetragener Verein Sitz im Ausland','Typ unbekannt') AS Kundentyp ,kategorie FROM t1 WHERE hdl_nr < 2000000 AND kategorie IN ('Prepaid','Mobilfunk') AND st_klasse = 'Workflow' GROUP BY kundentyp ORDER BY kategorie; drop table t1; + +# +# test case for #570 +# + +CREATE TABLE t1 ( + AUFNR varchar(12) NOT NULL default '', + PLNFL varchar(6) NOT NULL default '', + VORNR varchar(4) NOT NULL default '', + xstatus_vor smallint(5) unsigned NOT NULL default '0', + +); + +INSERT INTO t1 VALUES ('40004712','000001','0010',9); +INSERT INTO t1 VALUES ('40004712','000001','0020',0); + +UPDATE t1 SET t1.xstatus_vor = Greatest(t1.xstatus_vor,1) WHERE t1.aufnr = +"40004712" AND t1.plnfl = "000001" AND t1.vornr > "0010" ORDER BY t1.vornr +ASC LIMIT 1; From b2769e279239cca52c3f264724286b052357ed14 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 3 Jul 2003 17:36:33 +0300 Subject: [PATCH 117/237] trx0trx.c: Fix bug: group commit still did not work when we had MySQL binlogging on --- innobase/trx/trx0trx.c | 92 +++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 28 deletions(-) diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 9233e861784..095a9df9082 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -778,29 +778,53 @@ trx_commit_off_kernel( efficient here: call os_thread_yield here to allow also other trxs to come to commit! */ - /* We now flush the log, as the transaction made changes to - the database, making the transaction committed on disk. It is - enough that any one of the log groups gets written to disk. */ - /*-------------------------------------*/ - /* Most MySQL users run with srv_flush_.. set to 0: */ + /* Depending on the my.cnf options, we may now write the log + buffer to the log files, making the transaction durable if + the OS does not crash. We may also flush the log files to + disk, making the transaction durable also at an OS crash or a + power outage. - if (srv_flush_log_at_trx_commit != 0) { - if (srv_unix_file_flush_method != SRV_UNIX_NOSYNC - && srv_flush_log_at_trx_commit != 2 - && !trx->flush_log_later) { - - /* Write the log to the log files AND flush - them to disk */ + The idea in InnoDB's group commit is that a group of + transactions gather behind a trx doing a physical disk write + to log files, and when that physical write has been completed, + one of those transactions does a write which commits the whole + group. Note that this group commit will only bring benefit if + there are > 2 users in the database. Then at least 2 users can + gather behind one doing the physical log write to disk. - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE); - } else { - /* Write the log but do not flush it to disk */ + If we are calling trx_commit() under MySQL's binlog mutex, we + will delay possible log write and flush to a separate function + trx_commit_complete_for_mysql(), which is only called when the + thread has released the binlog mutex. This is to make the + group commit algorithm to work. Otherwise, the MySQL binlog + mutex would serialize all commits and prevent a group of + transactions from gathering. */ - log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE); - } - } + if (trx->flush_log_later) { + /* Do nothing yet */ + } else if (srv_flush_log_at_trx_commit == 0) { + /* Do nothing */ + } else if (srv_flush_log_at_trx_commit == 1) { + if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) { + /* Write the log but do not flush it to disk */ + + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE); + } else { + /* Write the log to the log files AND flush + them to disk */ + + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE); + } + } else if (srv_flush_log_at_trx_commit == 2) { + + /* Write the log but do not flush it to disk */ + + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE); + } else { + ut_a(0); + } trx->commit_lsn = lsn; @@ -1497,21 +1521,33 @@ trx_commit_complete_for_mysql( /* out: 0 or error number */ trx_t* trx) /* in: trx handle */ { - ut_a(trx); + dulint lsn = trx->commit_lsn; - if (srv_flush_log_at_trx_commit == 1 - && srv_unix_file_flush_method != SRV_UNIX_NOSYNC) { - - trx->op_info = (char *) "flushing log"; + ut_a(trx); - /* Flush the log files to disk */ + if (srv_flush_log_at_trx_commit == 0) { + /* Do nothing */ + } else if (srv_flush_log_at_trx_commit == 1) { + if (srv_unix_file_flush_method == SRV_UNIX_NOSYNC) { + /* Write the log but do not flush it to disk */ - log_write_up_to(trx->commit_lsn, LOG_WAIT_ONE_GROUP, TRUE); + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE); + } else { + /* Write the log to the log files AND flush them to + disk */ - trx->op_info = (char *) ""; - } + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, TRUE); + } + } else if (srv_flush_log_at_trx_commit == 2) { - return(0); + /* Write the log but do not flush it to disk */ + + log_write_up_to(lsn, LOG_WAIT_ONE_GROUP, FALSE); + } else { + ut_a(0); + } + + return(0); } /************************************************************************** From dbb95326b0c15ec92be949d24b1998f18eb92147 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Thu, 3 Jul 2003 20:57:51 +0500 Subject: [PATCH 118/237] Proposed fix for #751 Fields in key_expr (mysql_ha_read) wasn't linked to tables. Hmm. How did it work at all? --- mysql-test/r/alias.result | 1 + mysql-test/r/handler.result | 6 ++++++ mysql-test/t/alias.test | 2 ++ mysql-test/t/handler.test | 10 ++++++++++ sql/sql_handler.cc | 2 ++ 5 files changed, 21 insertions(+) diff --git a/mysql-test/r/alias.result b/mysql-test/r/alias.result index 55397705bdf..5ed10b58929 100644 --- a/mysql-test/r/alias.result +++ b/mysql-test/r/alias.result @@ -70,3 +70,4 @@ INSERT INTO t1 VALUES ('40004712','000001','0020',0); UPDATE t1 SET t1.xstatus_vor = Greatest(t1.xstatus_vor,1) WHERE t1.aufnr = "40004712" AND t1.plnfl = "000001" AND t1.vornr > "0010" ORDER BY t1.vornr ASC LIMIT 1; +drop table t1; diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 3be24305e09..525fd1a4495 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -146,3 +146,9 @@ alter table t1 type=MyISAM; handler t2 read first; Unknown table 't2' in HANDLER drop table t1; +create table t1(a int, index(a)); +insert into t1 values (1), (2), (3); +handler t1 open; +handler t1 read a=(W); +Unknown column 'W' in 'field list' +drop table t1; diff --git a/mysql-test/t/alias.test b/mysql-test/t/alias.test index 0dafc62430e..57b46181fa1 100644 --- a/mysql-test/t/alias.test +++ b/mysql-test/t/alias.test @@ -81,3 +81,5 @@ INSERT INTO t1 VALUES ('40004712','000001','0020',0); UPDATE t1 SET t1.xstatus_vor = Greatest(t1.xstatus_vor,1) WHERE t1.aufnr = "40004712" AND t1.plnfl = "000001" AND t1.vornr > "0010" ORDER BY t1.vornr ASC LIMIT 1; + +drop table t1; diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index 7020a4ab3d3..b1902c213bf 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -80,3 +80,13 @@ alter table t1 type=MyISAM; handler t2 read first; drop table t1; +# +#test for #751 +# +create table t1(a int, index(a)); +insert into t1 values (1), (2), (3); +handler t1 open; +--error 1054 +handler t1 read a=(W); +drop table t1; + diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index a98b6c13a00..c80c0444cb5 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -193,6 +193,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, Item *item; for (key_len=0 ; (item=it_ke++) ; key_part++) { + if (item->fix_fields(thd, tables)) + return -1; item->save_in_field(key_part->field, 1); key_len+=key_part->store_length; } From be22700954f00691118f14e8755f573684167bc4 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Thu, 3 Jul 2003 19:23:06 +0300 Subject: [PATCH 119/237] Fix for UNIXWARE 7 Remove unaligned warnings on Ia64 from client library when using --host Fix for replication when using many file descriptors --- include/my_global.h | 8 ++ libmysql/libmysql.c | 16 +++- mysql-test/r/symlink.result | 9 +- sql/mini_client.cc | 175 ++++++++++++++++++++++++------------ 4 files changed, 144 insertions(+), 64 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 673e5a22868..5ad12fc1f15 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -43,6 +43,10 @@ #define HAVE_ERRNO_AS_DEFINE #endif /* __CYGWIN__ */ +#if defined(i386) && !defined(__i386__) +#define __i386__ +#endif + /* Macros to make switching between C and C++ mode easier */ #ifdef __cplusplus #define C_MODE_START extern "C" { @@ -145,6 +149,10 @@ double my_ulonglong2double(unsigned long long A); C_MODE_END #endif /* _AIX */ +#ifdef UNIXWARE_7 +#define pthread_attr_setstacksize(A,B) /* setting stack breaks things */ +#endif + #ifdef HAVE_BROKEN_SNPRINTF /* HPUX 10.20 don't have this defined */ #undef HAVE_SNPRINTF #endif diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 3c8ac9f3387..aa169335dfb 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1595,6 +1595,18 @@ mysql_connect(MYSQL *mysql,const char *host, #endif +/* + The following union is used to force a struct to be double allgined. + This is to avoid warings with gethostname_r() on Linux itanium systems +*/ + +typedef union +{ + double tmp; + char buff[GETHOSTBYNAME_BUFF_SIZE]; +} gethostbyname_buff; + + /* Note that the mysql argument must be initialized with mysql_init() before calling mysql_real_connect ! @@ -1766,8 +1778,8 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, { int tmp_errno; struct hostent tmp_hostent,*hp; - char buff2[GETHOSTBYNAME_BUFF_SIZE]; - hp = my_gethostbyname_r(host,&tmp_hostent,buff2,sizeof(buff2), + gethostbyname_buff buff2; + hp = my_gethostbyname_r(host,&tmp_hostent,buff2.buff,sizeof(buff2), &tmp_errno); if (!hp) { diff --git a/mysql-test/r/symlink.result b/mysql-test/r/symlink.result index 5626bc0fe11..ab699ac4c4e 100644 --- a/mysql-test/r/symlink.result +++ b/mysql-test/r/symlink.result @@ -1,4 +1,5 @@ drop table if exists t1,t2,t7,t8,t9; +drop database if exists mysqltest; create table t1 (a int not null auto_increment, b char(16) not null, primary key (a)); create table t2 (a int not null auto_increment, b char(16) not null, primary key (a)); insert into t1 (b) values ("test"),("test1"),("test2"),("test3"); @@ -49,11 +50,11 @@ Got one of the listed errors Got one of the listed errors Got one of the listed errors Got one of the listed errors -alter table t9 rename test_mysqltest.t9; -select count(*) from test_mysqltest.t9; +alter table t9 rename mysqltest.t9; +select count(*) from mysqltest.t9; count(*) 16724 -show create table test_mysqltest.t9; +show create table mysqltest.t9; Table Create Table t9 CREATE TABLE `t9` ( `a` int(11) NOT NULL auto_increment, @@ -62,4 +63,4 @@ t9 CREATE TABLE `t9` ( `d` int(11) NOT NULL default '0', PRIMARY KEY (`a`) ) TYPE=MyISAM -drop database test_mysqltest; +drop database mysqltest; diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 6489685c923..1b625a81b0c 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -83,7 +83,9 @@ static int mc_read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths); static MYSQL_DATA *mc_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, uint fields); - +#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__)) +static int wait_for_data(my_socket fd, uint timeout); +#endif #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES) @@ -232,93 +234,150 @@ static void mc_free_old_query(MYSQL *mysql) /**************************************************************************** -* A modified version of connect(). mc_sock_connect() allows you to specify -* a timeout value, in seconds, that we should wait until we -* derermine we can't connect to a particular host. If timeout is 0, -* mc_sock_connect() will behave exactly like connect(). -* -* Base version coded by Steve Bernacki, Jr. + A modified version of connect(). my_connect() allows you to specify + a timeout value, in seconds, that we should wait until we + derermine we can't connect to a particular host. If timeout is 0, + my_connect() will behave exactly like connect(). + + Base version coded by Steve Bernacki, Jr. *****************************************************************************/ -static int mc_sock_connect(my_socket s, const struct sockaddr *name, - uint namelen, uint to) +static int mc_sock_connect(my_socket fd, const struct sockaddr *name, + uint namelen, uint timeout) { #if defined(__WIN__) || defined(OS2) || defined(__NETWARE__) - return connect(s, (struct sockaddr*) name, namelen); + return connect(fd, (struct sockaddr*) name, namelen); #else int flags, res, s_err; - SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); - fd_set sfds; - struct timeval tv; - /* If they passed us a timeout of zero, we should behave - * exactly like the normal connect() call does. - */ + /* + If they passed us a timeout of zero, we should behave + exactly like the normal connect() call does. + */ - if (to == 0) - return connect(s, (struct sockaddr*) name, namelen); + if (timeout == 0) + return connect(fd, (struct sockaddr*) name, namelen); - flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */ + flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */ #ifdef O_NONBLOCK - fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */ + fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */ #endif - res = connect(s, (struct sockaddr*) name, namelen); - s_err = errno; /* Save the error... */ - fcntl(s, F_SETFL, flags); + res= connect(fd, (struct sockaddr*) name, namelen); + s_err= errno; /* Save the error... */ + fcntl(fd, F_SETFL, flags); if ((res != 0) && (s_err != EINPROGRESS)) { - errno = s_err; /* Restore it */ + errno= s_err; /* Restore it */ return(-1); } if (res == 0) /* Connected quickly! */ return(0); + return wait_for_data(fd, timeout); +#endif +} - /* Otherwise, our connection is "in progress." We can use - * the select() call to wait up to a specified period of time - * for the connection to suceed. If select() returns 0 - * (after waiting howevermany seconds), our socket never became - * writable (host is probably unreachable.) Otherwise, if - * select() returns 1, then one of two conditions exist: - * - * 1. An error occured. We use getsockopt() to check for this. - * 2. The connection was set up sucessfully: getsockopt() will - * return 0 as an error. - * - * Thanks goes to Andrew Gierth - * who posted this method of timing out a connect() in - * comp.unix.programmer on August 15th, 1997. - */ + +/* + Wait up to timeout seconds for a connection to be established. + + We prefer to do this with poll() as there is no limitations with this. + If not, we will use select() +*/ + +#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__)) + +static int wait_for_data(my_socket fd, uint timeout) +{ +#ifdef HAVE_POLL + struct pollfd ufds; + int res; + + ufds.fd= fd; + ufds.events= POLLIN | POLLPRI; + if (!(res= poll(&ufds, 1, (int) timeout*1000))) + { + errno= EINTR; + return -1; + } + if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI))) + return -1; + return 0; +#else + SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); + fd_set sfds; + struct timeval tv; + time_t start_time, now_time; + int res, s_err; + + if (fd >= FD_SETSIZE) /* Check if wrong error */ + return 0; /* Can't use timeout */ + + /* + Our connection is "in progress." We can use the select() call to wait + up to a specified period of time for the connection to suceed. + If select() returns 0 (after waiting howevermany seconds), our socket + never became writable (host is probably unreachable.) Otherwise, if + select() returns 1, then one of two conditions exist: + + 1. An error occured. We use getsockopt() to check for this. + 2. The connection was set up sucessfully: getsockopt() will + return 0 as an error. + + Thanks goes to Andrew Gierth + who posted this method of timing out a connect() in + comp.unix.programmer on August 15th, 1997. + */ FD_ZERO(&sfds); - FD_SET(s, &sfds); - tv.tv_sec = (long) to; - tv.tv_usec = 0; -#ifdef HPUX10 - res = select(s+1, NULL, (int*) &sfds, NULL, &tv); -#else - res = select(s+1, NULL, &sfds, NULL, &tv); -#endif /* HPUX10 */ - if (res <= 0) /* Never became writable */ - return(-1); - - /* select() returned something more interesting than zero, let's - * see if we have any errors. If the next two statements pass, - * we've got an open socket! + FD_SET(fd, &sfds); + /* + select could be interrupted by a signal, and if it is, + the timeout should be adjusted and the select restarted + to work around OSes that don't restart select and + implementations of select that don't adjust tv upon + failure to reflect the time remaining */ + start_time = time(NULL); + for (;;) + { + tv.tv_sec = (long) timeout; + tv.tv_usec = 0; +#if defined(HPUX10) && defined(THREAD) + if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0) + break; +#else + if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0) + break; +#endif + if (res == 0) /* timeout */ + return -1; + now_time=time(NULL); + timeout-= (uint) (now_time - start_time); + if (errno != EINTR || (int) timeout <= 0) + return -1; + } + + /* + select() returned something more interesting than zero, let's + see if we have any errors. If the next two statements pass, + we've got an open socket! + */ s_err=0; - if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) return(-1); if (s_err) - { // getsockopt() could succeed + { /* getsockopt could succeed */ errno = s_err; - return(-1); // but return an error... + return(-1); /* but return an error... */ } - return(0); /* It's all good! */ -#endif + return (0); /* ok */ +#endif /* HAVE_POLL */ } +#endif /* defined(__WIN__) || defined(OS2) || defined(__NETWARE__) */ + /***************************************************************************** ** read a packet from server. Give error message if socket was down From fd4a1d4e549d10ca36ce76a9a0e6c1ca8605332e Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Thu, 3 Jul 2003 23:24:23 +0500 Subject: [PATCH 120/237] Fix for #739 check for negative count in RPAD added --- mysql-test/r/func_str.result | 10 ++++++++++ mysql-test/t/func_str.test | 14 ++++++++++++++ sql/item_strfunc.cc | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 09818c14462..0bac5111a05 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -247,3 +247,13 @@ elt(status_wnio,data_podp) NULL NULL DROP TABLE t1; +CREATE TABLE t1 ( +title text +) TYPE=MyISAM; +INSERT INTO t1 VALUES ('Congress reconvenes in September to debate welfare and adult education'); +INSERT INTO t1 VALUES ('House passes the CAREERS bill'); +SELECT CONCAT("",RPAD("",(55 - LENGTH(title)),".")) from t1; +CONCAT("",RPAD("",(55 - LENGTH(title)),".")) +NULL +.......................... +DROP TABLE t1; diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 476629f98d3..5ea3654134b 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -137,3 +137,17 @@ INSERT INTO t1 VALUES (8,NULL,'real'); INSERT INTO t1 VALUES (9,NULL,'nowy'); SELECT elt(status_wnio,data_podp) FROM t1 GROUP BY wid; DROP TABLE t1; + +# +# test for #739 + +CREATE TABLE t1 ( + title text +) TYPE=MyISAM; + +INSERT INTO t1 VALUES ('Congress reconvenes in September to debate welfare and adult education'); +INSERT INTO t1 VALUES ('House passes the CAREERS bill'); + +SELECT CONCAT("",RPAD("",(55 - LENGTH(title)),".")) from t1; + +DROP TABLE t1; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 838fca807a2..caaff4d1613 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1804,7 +1804,7 @@ String *Item_func_rpad::val_str(String *str) String *res =args[0]->val_str(str); String *rpad = args[2]->val_str(str); - if (!res || args[1]->null_value || !rpad) + if (!res || args[1]->null_value || !rpad || count < 0) goto err; null_value=0; if (count <= (int32) (res_length=res->length())) From 2a1f87ff726219123d54dfb856956bff6ea2cbf7 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 3 Jul 2003 21:25:55 +0300 Subject: [PATCH 121/237] Many files: Remove potential starvation of a full log buffer flush: only flush up to the lsn which was the largest at the time when we requested the full log buffer flush os0sync.h, os0sync.c: Fix a bug in os_event on Unix: even though we signaled the event, some threads could continue waiting if the event became nonsignaled quickly again; this made group commit less efficient than it should be --- innobase/btr/btr0btr.c | 29 +++++++++++++++++++++++++++++ innobase/include/log0log.h | 6 ++++++ innobase/include/os0sync.h | 8 ++++++-- innobase/log/log0log.c | 25 +++++++++++++++++++++++-- innobase/os/os0sync.c | 15 ++++++++++++--- innobase/row/row0mysql.c | 2 +- innobase/srv/srv0srv.c | 20 +++++++++++--------- innobase/trx/trx0trx.c | 4 ++++ sql/ha_innodb.cc | 10 +++++----- 9 files changed, 97 insertions(+), 22 deletions(-) diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 51c164b7cef..d8a0959e47f 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -822,9 +822,16 @@ btr_page_reorganize_low( { page_t* new_page; ulint log_mode; + ulint data_size1; + ulint data_size2; + ulint max_ins_size1; + ulint max_ins_size2; ut_ad(mtr_memo_contains(mtr, buf_block_align(page), MTR_MEMO_PAGE_X_FIX)); + data_size1 = page_get_data_size(page); + max_ins_size1 = page_get_max_insert_size_after_reorganize(page, 1); + /* Write the log record */ mlog_write_initial_log_record(page, MLOG_PAGE_REORGANIZE, mtr); @@ -859,6 +866,19 @@ btr_page_reorganize_low( lock_move_reorganize_page(page, new_page); } + data_size2 = page_get_data_size(page); + max_ins_size2 = page_get_max_insert_size_after_reorganize(page, 1); + + if (data_size1 != data_size2 || max_ins_size1 != max_ins_size2) { + buf_page_print(page); + buf_page_print(new_page); + 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", + data_size1, data_size2, max_ins_size1, max_ins_size2); + } + buf_frame_free(new_page); /* Restore logging mode */ @@ -1945,11 +1965,20 @@ btr_compress( btr_page_reorganize(merge_page, mtr); + max_ins_size = page_get_max_insert_size(merge_page, n_recs); + ut_ad(page_validate(merge_page, cursor->index)); ut_ad(page_get_max_insert_size(merge_page, n_recs) == max_ins_size_reorg); } + if (data_size > max_ins_size) { + + /* Add fault tolerance, though this should never happen */ + + return; + } + btr_search_drop_page_hash_index(page); /* Remove the page from the level list */ diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index 4e1404b15fe..e79e914e4f6 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -173,6 +173,12 @@ log_write_up_to( /* in: TRUE if we want the written log also to be flushed to disk */ /******************************************************************** +Does a syncronous flush of the log buffer to disk. */ + +void +log_buffer_flush_to_disk(void); +/*==========================*/ +/******************************************************************** Advances the smallest lsn for which there are unflushed dirty blocks in the buffer pool and also may make a new checkpoint. NOTE: this function may only be called if the calling thread owns no synchronization objects! */ diff --git a/innobase/include/os0sync.h b/innobase/include/os0sync.h index 634507467f9..e1cf263216e 100644 --- a/innobase/include/os0sync.h +++ b/innobase/include/os0sync.h @@ -36,8 +36,12 @@ typedef os_event_struct_t* os_event_t; struct os_event_struct { os_fast_mutex_t os_mutex; /* this mutex protects the next fields */ - ibool is_set; /* this is TRUE if the next mutex is - not reserved */ + ibool is_set; /* this is TRUE when the event is + in the signaled state, i.e., a thread + does not stop if it tries to wait for + this event */ + ib_longlong signal_count; /* this is incremented each time + the event becomes signaled */ pthread_cond_t cond_var; /* condition variable is used in waiting for the event */ UT_LIST_NODE_T(os_event_struct_t) os_event_list; diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index b5ce1a3d97b..53ca97baaa0 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -178,7 +178,8 @@ loop: /* Not enough free space, do a syncronous flush of the log buffer */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ALL_GROUPS, TRUE); + + log_buffer_flush_to_disk(); count++; @@ -1364,6 +1365,24 @@ do_waits: } } +/******************************************************************** +Does a syncronous flush of the log buffer to disk. */ + +void +log_buffer_flush_to_disk(void) +/*==========================*/ +{ + dulint lsn; + + mutex_enter(&(log_sys->mutex)); + + lsn = log_sys->lsn; + + mutex_exit(&(log_sys->mutex)); + + log_write_up_to(lsn, LOG_WAIT_ALL_GROUPS, TRUE); +} + /******************************************************************** Tries to establish a big enough margin of free space in the log buffer, such that a new log entry can be catenated without an immediate need for a flush. */ @@ -1374,6 +1393,7 @@ log_flush_margin(void) { ibool do_flush = FALSE; log_t* log = log_sys; + dulint lsn; mutex_enter(&(log->mutex)); @@ -1384,13 +1404,14 @@ log_flush_margin(void) free space */ } else { do_flush = TRUE; + lsn = log->lsn; } } mutex_exit(&(log->mutex)); if (do_flush) { - log_write_up_to(ut_dulint_max, LOG_NO_WAIT, FALSE); + log_write_up_to(lsn, LOG_NO_WAIT, FALSE); } } diff --git a/innobase/os/os0sync.c b/innobase/os/os0sync.c index bf5fc57bf57..827d68501db 100644 --- a/innobase/os/os0sync.c +++ b/innobase/os/os0sync.c @@ -143,6 +143,7 @@ os_event_create( ut_a(0 == pthread_cond_init(&(event->cond_var), NULL)); #endif event->is_set = FALSE; + event->signal_count = 0; #endif /* __WIN__ */ /* Put to the list of events */ @@ -218,6 +219,7 @@ os_event_set( /* Do nothing */ } else { event->is_set = TRUE; + event->signal_count += 1; ut_a(0 == pthread_cond_broadcast(&(event->cond_var))); } @@ -310,9 +312,15 @@ os_event_wait( os_thread_exit(NULL); } #else + ib_longlong old_signal_count; + os_fast_mutex_lock(&(event->os_mutex)); + + old_signal_count = event->signal_count; loop: - if (event->is_set == TRUE) { + if (event->is_set == TRUE + || event->signal_count != old_signal_count) { + os_fast_mutex_unlock(&(event->os_mutex)); if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { @@ -326,8 +334,9 @@ loop: pthread_cond_wait(&(event->cond_var), &(event->os_mutex)); - /* Solaris manual said that spurious wakeups may occur: we have - to check the 'is_set' variable again */ + /* Solaris manual said that spurious wakeups may occur: we have to + check if the event really has been signaled after we came here to + wait */ goto loop; #endif diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index dc2a50c4f0c..af73c2f62c3 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1655,7 +1655,7 @@ row_drop_table_for_mysql_in_background( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); trx_commit_for_mysql(trx); diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index d13d499dd17..083cbfd2609 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -2836,7 +2836,7 @@ loop: at transaction commit */ srv_main_thread_op_info = (char*)"flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* If there were less than 5 i/os during the one second sleep, we assume that there is free @@ -2852,10 +2852,9 @@ loop: (char*)"doing insert buffer merge"; ibuf_contract_for_n_pages(TRUE, 5); - srv_main_thread_op_info = - (char*)"flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, - TRUE); + srv_main_thread_op_info = (char*)"flushing log"; + + log_buffer_flush_to_disk(); } if (buf_get_modified_ratio_pct() > @@ -2905,7 +2904,7 @@ loop: buf_flush_batch(BUF_FLUSH_LIST, 100, ut_dulint_max); srv_main_thread_op_info = (char*) "flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); } /* We run a batch of insert buffer merge every 10 seconds, @@ -2915,7 +2914,7 @@ loop: ibuf_contract_for_n_pages(TRUE, 5); srv_main_thread_op_info = (char*)"flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* We run a full purge every 10 seconds, even if the server were active */ @@ -2939,8 +2938,7 @@ loop: if (difftime(current_time, last_flush_time) > 1) { srv_main_thread_op_info = (char*) "flushing log"; - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, - TRUE); + log_buffer_flush_to_disk(); last_flush_time = current_time; } } @@ -3060,6 +3058,10 @@ flush_loop: (char*) "waiting for buffer pool flush to end"; buf_flush_wait_batch_end(BUF_FLUSH_LIST); + srv_main_thread_op_info = (char*) "flushing log"; + + log_buffer_flush_to_disk(); + srv_main_thread_op_info = (char*)"making checkpoint"; log_checkpoint(TRUE, FALSE); diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 095a9df9082..0dead50264b 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -1524,6 +1524,8 @@ trx_commit_complete_for_mysql( dulint lsn = trx->commit_lsn; ut_a(trx); + + trx->op_info = (char*)"flushing log"; if (srv_flush_log_at_trx_commit == 0) { /* Do nothing */ @@ -1547,6 +1549,8 @@ trx_commit_complete_for_mysql( ut_a(0); } + trx->op_info = (char*)""; + return(0); } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 2cc64b18706..8edec984962 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -915,7 +915,7 @@ innobase_flush_logs(void) DBUG_ENTER("innobase_flush_logs"); - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); DBUG_RETURN(result); } @@ -3538,7 +3538,7 @@ ha_innobase::create( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); innobase_table = dict_table_get(norm_name, NULL); @@ -3613,7 +3613,7 @@ ha_innobase::delete_table( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* Tell the InnoDB server that there might be work for utility threads: */ @@ -3683,7 +3683,7 @@ innobase_drop_database( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* Tell the InnoDB server that there might be work for utility threads: */ @@ -3755,7 +3755,7 @@ ha_innobase::rename_table( the InnoDB data dictionary get out-of-sync if the user runs with innodb_flush_log_at_trx_commit = 0 */ - log_write_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP, TRUE); + log_buffer_flush_to_disk(); /* Tell the InnoDB server that there might be work for utility threads: */ From 0abd1539fad1173c22d94248133ff1cfbf9d9602 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Thu, 3 Jul 2003 22:48:13 +0300 Subject: [PATCH 122/237] ha_innodb.cc: Since the mysql interactive client or some other phase in communication cuts > 64 kB strings to very short, restrict the output of SHOW INNODB STATUS to at most 60 kB --- sql/ha_innodb.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 8edec984962..9857628ccc8 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -4556,12 +4556,12 @@ innodb_show_status( innobase_release_stat_resources(trx); - /* We let the InnoDB Monitor to output at most 200 kB of text, add - a safety margin of 10 kB for buffer overruns */ + /* We let the InnoDB Monitor to output at most 60 kB of text, add + a safety margin of 100 kB for buffer overruns */ - buf = (char*)ut_malloc(210 * 1024); + buf = (char*)ut_malloc(160 * 1024); - srv_sprintf_innodb_monitor(buf, 200 * 1024); + srv_sprintf_innodb_monitor(buf, 60 * 1024); List field_list; From e82d5eeb9b470f8b02b36512d4cf6a6b5c77e4e1 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Thu, 3 Jul 2003 23:41:07 +0300 Subject: [PATCH 123/237] Fix for bug #676 A security leak with SHOW TABLES/ TABLE STATUS FROM db ... --- sql/sql_parse.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1ac4120187b..cc124b492a0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2171,6 +2171,14 @@ mysql_execute_command(void) } if (check_access(thd,SELECT_ACL,db,&thd->col_access)) goto error; /* purecov: inspected */ + if (!thd->col_access && grant_option && check_grant_db(thd,db)) + { + net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, + thd->priv_user, + thd->priv_host, + db); + goto error; + } /* grant is checked in mysqld_show_tables */ if (select_lex->options & SELECT_DESCRIBE) res= mysqld_extend_show_tables(thd,db, From f3af0d7ce423d3b28de463c430f4ff4bef8b925e Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Fri, 4 Jul 2003 03:18:15 +0300 Subject: [PATCH 124/237] Status query on killed mysql connection results in segmentation fault (Bug #738) Added MAX_PASSWORD_LENGTH. This increased master-slave passwords to 32 bytes (Bug #766) Fixed server crash on purge master logs or show master logs when binlog is off. (Bug #733) --- client/mysql.cc | 3 ++- configure.in | 22 ++++++++++++---------- include/my_global.h | 4 ---- sql/mysql_priv.h | 1 + sql/slave.h | 11 +++++------ sql/sql_repl.cc | 25 +++++++++++++------------ sql/sql_repl.h | 2 +- strings/strmake.c | 2 +- 8 files changed, 35 insertions(+), 35 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index 81f4b19f7c6..4fe832a790e 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2329,7 +2329,8 @@ com_status(String *buffer __attribute__((unused)), (void) mysql_fetch_row(result); // Read eof } #ifdef HAVE_OPENSSL - if (mysql.net.vio->ssl_ && SSL_get_cipher(mysql.net.vio->ssl_)) + if (mysql.net.vio && mysql.net.vio->ssl_ && + SSL_get_cipher(mysql.net.vio->ssl_)) tee_fprintf(stdout, "SSL:\t\t\tCipher in use is %s\n", SSL_get_cipher(mysql.net.vio->ssl_)); else diff --git a/configure.in b/configure.in index a33ccd4a311..38847b5217e 100644 --- a/configure.in +++ b/configure.in @@ -1282,12 +1282,12 @@ then AC_MSG_ERROR([On SCO UNIX MySQL must be compiled with gcc. See the Installation chapter in the Reference Manual.]); fi AC_MSG_RESULT("yes") - # Hack for SCO UnixWare 7.1 + # Hack for SCO UnixWare 7.1.x # elif test "$with_named_thread" = "no" then AC_MSG_RESULT("no") - AC_MSG_CHECKING("SCO UnixWare 7.1 native threads") + AC_MSG_CHECKING("SCO UnixWare 7.1.x native threads") if expr "$SYSTEM_TYPE" : ".*sco.*" > /dev/null then if test -f /usr/lib/libthread.so -o -f /usr/lib/libthreadT.so @@ -1310,11 +1310,11 @@ then AC_MSG_CHECKING("for gcc") if expr "$CC" : ".*gcc.*" then - CC="$CC -pthread -DUNIXWARE_7"; - CXX="$CXX -pthread -DUNIXWARE_7"; + CC="$CC -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; + CXX="$CXX -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; else - CC="$CC -Kthread -DUNIXWARE_7"; - CXX="$CXX -Kthread -DUNIXWARE_7"; + CC="$CC -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; + CXX="$CXX -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; fi else { echo "configure: error: Can't find thread libs on SCO UnixWare7. See the Installation chapter in the Reference Manual." 1>&2; exit 1; }; @@ -1350,10 +1350,11 @@ then AC_MSG_CHECKING("for gcc") if expr "$CC" : ".*gcc.*" then - { echo "configure: error: On SCO UnixWare7 MySQL must be compiled with cc. See the Installation chapter in the Reference Manual." 1>&2; exit 1; }; + CC="$CC -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; + CXX="$CXX -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; else - CC="$CC -Kthread -DUNIXWARE_7"; - CXX="$CXX -Kthread -DUNIXWARE_7"; + CC="$CC -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; + CXX="$CXX -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; fi AC_MSG_RESULT("yes") else @@ -1385,7 +1386,8 @@ then AC_MSG_CHECKING("for gcc") if expr "$CC" : ".*gcc.*" then - { echo "configure: error: On OpenUNIX8 and UnixWare7 MySQL must be compiled with cc. See the Installation chapter in the Reference Manual." 1>&2; exit 1; }; + CC="$CC -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; + CXX="$CXX -pthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; else CC="$CC -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; CXX="$CXX -Kthread -DUNIXWARE_7 -DHAVE_BROKEN_RWLOCK"; diff --git a/include/my_global.h b/include/my_global.h index 5ad12fc1f15..9d08977a7cd 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -149,10 +149,6 @@ double my_ulonglong2double(unsigned long long A); C_MODE_END #endif /* _AIX */ -#ifdef UNIXWARE_7 -#define pthread_attr_setstacksize(A,B) /* setting stack breaks things */ -#endif - #ifdef HAVE_BROKEN_SNPRINTF /* HPUX 10.20 don't have this defined */ #undef HAVE_SNPRINTF #endif diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 14680306e5d..ce23abb6b2c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -59,6 +59,7 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define ACL_CACHE_SIZE 256 #define HASH_PASSWORD_LENGTH 16 +#define MAX_PASSWORD_LENGTH 32 #define HOST_CACHE_SIZE 128 #define MAX_ACCEPT_RETRY 10 // Test accept this many times #define MAX_FIELDS_BEFORE_HASH 32 diff --git a/sql/slave.h b/sql/slave.h index 6a73c86d304..cae8c6ae241 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -250,20 +250,20 @@ Log_event* next_event(RELAY_LOG_INFO* rli); typedef struct st_master_info { char master_log_name[FN_REFLEN]; + char host[HOSTNAME_LENGTH+1]; + char user[USERNAME_LENGTH+1]; + char password[MAX_PASSWORD_LENGTH+1]; my_off_t master_log_pos; File fd; // we keep the file open, so we need to remember the file pointer IO_CACHE file; /* the variables below are needed because we can change masters on the fly */ - char host[HOSTNAME_LENGTH+1]; - char user[USERNAME_LENGTH+1]; - char password[HASH_PASSWORD_LENGTH+1]; pthread_mutex_t data_lock,run_lock; pthread_cond_t data_cond,start_cond,stop_cond; THD *io_thd; MYSQL* mysql; - uint32 file_id; /* for 3.23 load data infile */ + uint32 file_id; /* for 3.23 load data infile */ RELAY_LOG_INFO rli; uint port; uint connect_retry; @@ -271,12 +271,11 @@ typedef struct st_master_info int events_till_abort; #endif bool inited; - enum enum_binlog_formats old_format; /* master binlog is in 3.23 format */ + enum enum_binlog_formats old_format; /* binlog is in 3.23 format */ volatile bool abort_slave, slave_running; volatile ulong slave_run_id; bool ignore_stop_event; - st_master_info() :fd(-1), io_thd(0), inited(0), old_format(BINLOG_FORMAT_CURRENT), abort_slave(0),slave_running(0), slave_run_id(0) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 8fb82798a45..e775a5d712e 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -267,9 +267,13 @@ int purge_master_logs(THD* thd, const char* to_log) { char search_file_name[FN_REFLEN]; const char* errmsg = 0; + int res; + + if (!mysql_bin_log.is_open()) + goto end; mysql_bin_log.make_log_name(search_file_name, to_log); - int res = mysql_bin_log.purge_logs(thd, search_file_name); + res = mysql_bin_log.purge_logs(thd, search_file_name); switch(res) { case 0: break; @@ -292,9 +296,9 @@ binlog purge"; break; send_error(&thd->net, 0, errmsg); return 1; } - else - send_ok(&thd->net); +end: + send_ok(&thd->net); return 0; } @@ -886,7 +890,7 @@ int change_master(THD* thd, MASTER_INFO* mi) if (lex_mi->log_file_name) strmake(mi->master_log_name, lex_mi->log_file_name, - sizeof(mi->master_log_name)); + sizeof(mi->master_log_name)-1); if (lex_mi->pos) { mi->master_log_pos= lex_mi->pos; @@ -895,11 +899,11 @@ int change_master(THD* thd, MASTER_INFO* mi) DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); if (lex_mi->host) - strmake(mi->host, lex_mi->host, sizeof(mi->host)); + strmake(mi->host, lex_mi->host, sizeof(mi->host)-1); if (lex_mi->user) - strmake(mi->user, lex_mi->user, sizeof(mi->user)); + strmake(mi->user, lex_mi->user, sizeof(mi->user)-1); if (lex_mi->password) - strmake(mi->password, lex_mi->password, sizeof(mi->password)); + strmake(mi->password, lex_mi->password, sizeof(mi->password)-1); if (lex_mi->port) mi->port = lex_mi->port; if (lex_mi->connect_retry) @@ -1137,7 +1141,6 @@ int show_binlog_info(THD* thd) int show_binlogs(THD* thd) { - const char *errmsg; IO_CACHE *index_file; char fname[FN_REFLEN]; NET* net = &thd->net; @@ -1148,8 +1151,8 @@ int show_binlogs(THD* thd) if (!mysql_bin_log.is_open()) { //TODO: Replace with ER() error message - errmsg= "You are not using binary logging"; - goto err_with_msg; + send_error(net, 0, "You are not using binary logging"); + return 1; } field_list.push_back(new Item_empty_string("Log_name", 255)); @@ -1174,8 +1177,6 @@ int show_binlogs(THD* thd) send_eof(net); return 0; -err_with_msg: - send_error(net, 0, errmsg); err: mysql_bin_log.unlock_index(); return 1; diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 15435382b08..c73744c4b7c 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -6,7 +6,7 @@ typedef struct st_slave_info uint32 rpl_recovery_rank, master_id; char host[HOSTNAME_LENGTH+1]; char user[USERNAME_LENGTH+1]; - char password[HASH_PASSWORD_LENGTH+1]; + char password[MAX_PASSWORD_LENGTH+1]; uint16 port; THD* thd; } SLAVE_INFO; diff --git a/strings/strmake.c b/strings/strmake.c index 2e384fc168a..d2252f648f6 100644 --- a/strings/strmake.c +++ b/strings/strmake.c @@ -21,7 +21,7 @@ strmake(dst,src,length) moves length characters, or until end, of src to dst and appends a closing NUL to dst. - Note that is strlen(src) >= length then dst[length] will be set to \0 + Note that if strlen(src) >= length then dst[length] will be set to \0 strmake() returns pointer to closing null */ From c835c8686458d941313cd14f9d4851ad1e14e199 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Fri, 4 Jul 2003 11:06:58 +0300 Subject: [PATCH 125/237] Fixed memory/lock leak from bug fix --- sql/sql_handler.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index c80c0444cb5..d8e2479d6fb 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -194,7 +194,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, for (key_len=0 ; (item=it_ke++) ; key_part++) { if (item->fix_fields(thd, tables)) - return -1; + goto err; item->save_in_field(key_part->field, 1); key_len+=key_part->store_length; } From 40b6d074398e0b93fdf5a68553689550f0cd5068 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Fri, 4 Jul 2003 12:55:25 +0200 Subject: [PATCH 126/237] handler should be used with constant expressions only (or rand) --- mysql-test/r/handler.result | 2 ++ mysql-test/t/handler.test | 2 ++ sql/sql_handler.cc | 7 ++++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 525fd1a4495..1973797ae79 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -151,4 +151,6 @@ insert into t1 values (1), (2), (3); handler t1 open; handler t1 read a=(W); Unknown column 'W' in 'field list' +handler t1 read a=(a); +Wrong arguments to HANDLER ... READ drop table t1; diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index b1902c213bf..39ceab7ab22 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -88,5 +88,7 @@ insert into t1 values (1), (2), (3); handler t1 open; --error 1054 handler t1 read a=(W); +--error 1210 +handler t1 read a=(a); drop table t1; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index c80c0444cb5..42cfcb51377 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -194,7 +194,12 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, for (key_len=0 ; (item=it_ke++) ; key_part++) { if (item->fix_fields(thd, tables)) - return -1; + goto err; + if (item->used_tables() & ~RAND_TABLE_BIT) + { + my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ"); + goto err; + } item->save_in_field(key_part->field, 1); key_len+=key_part->store_length; } From 15346c8a6675e5dc57fea1e804e9cba786e6931f Mon Sep 17 00:00:00 2001 From: "ram@mysql.r18.ru" <> Date: Fri, 4 Jul 2003 17:15:16 +0500 Subject: [PATCH 127/237] fix and test case for the bug #787: HANDLER without INDEX doesn't work with deleted rows --- mysql-test/r/handler.result | 19 ++++++++++++++++++ mysql-test/t/handler.test | 15 ++++++++++++++ sql/sql_handler.cc | 39 ++++++++++++++++--------------------- 3 files changed, 51 insertions(+), 22 deletions(-) diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 1973797ae79..4af38807518 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -146,6 +146,25 @@ alter table t1 type=MyISAM; handler t2 read first; Unknown table 't2' in HANDLER drop table t1; +create table t1 (a int); +insert into t1 values (1),(2),(3),(4),(5),(6); +delete from t1 limit 2; +handler t1 open; +handler t1 read first; +a +3 +handler t1 read first limit 1,1; +a +4 +handler t1 read first limit 2,2; +a +5 +6 +delete from t1 limit 3; +handler t1 read first; +a +6 +drop table t1; create table t1(a int, index(a)); insert into t1 values (1), (2), (3); handler t1 open; diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index 39ceab7ab22..737b220c805 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -80,6 +80,21 @@ alter table t1 type=MyISAM; handler t2 read first; drop table t1; +# +# test case for the bug #787 +# + +create table t1 (a int); +insert into t1 values (1),(2),(3),(4),(5),(6); +delete from t1 limit 2; +handler t1 open; +handler t1 read first; +handler t1 read first limit 1,1; +handler t1 read first limit 2,2; +delete from t1 limit 3; +handler t1 read first; +drop table t1; + # #test for #751 # diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 42cfcb51377..e685ea3a059 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -219,6 +219,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, goto err; } + if (err == HA_ERR_RECORD_DELETED) + continue; if (err) { if (err != HA_ERR_KEY_NOT_FOUND && err != HA_ERR_END_OF_FILE) @@ -230,31 +232,24 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, } goto ok; } - if (cond) + if (cond && !cond->val_int()) + continue; + if (!err && num_rows >= offset_limit) { - err=err; - if (!cond->val_int()) - continue; - } - if (num_rows>=offset_limit) - { - if (!err) + String *packet = &thd->packet; + Item *item; + packet->length(0); + it.rewind(); + while ((item=it++)) { - String *packet = &thd->packet; - Item *item; - packet->length(0); - it.rewind(); - while ((item=it++)) - { - if (item->send(thd,packet)) - { - packet->free(); // Free used - my_error(ER_OUT_OF_RESOURCES,MYF(0)); - goto err; - } - } - my_net_write(&thd->net, (char*)packet->ptr(), packet->length()); + if (item->send(thd,packet)) + { + packet->free(); // Free used + my_error(ER_OUT_OF_RESOURCES,MYF(0)); + goto err; + } } + my_net_write(&thd->net, (char*)packet->ptr(), packet->length()); } num_rows++; } From 6a40b8e889fbab545853cc92c840cc328a95e041 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Fri, 4 Jul 2003 14:42:57 +0200 Subject: [PATCH 128/237] merge + order by (bug #515) temporary fix properly fixed in 4.1 --- mysql-test/r/merge.result | 2 ++ sql/ha_myisammrg.h | 3 ++- sql/sql_select.cc | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result index cf39faea41b..650fdb1c77b 100644 --- a/mysql-test/r/merge.result +++ b/mysql-test/r/merge.result @@ -607,4 +607,6 @@ x y 1 3 select * from t3 where x = 1 and y < 5 order by y desc; x y +1 3 +1 2 drop table t1,t2,t3; diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index 440b51e660f..dd649fe8fcb 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -40,7 +40,8 @@ class ha_myisammrg: public handler } ulong index_flags(uint inx) const { - ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER); + ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | + HA_NOT_READ_PREFIX_LAST); // This - last - flag is ONLY for 4.0 !!! return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ? 0 : HA_KEY_READ_ONLY)); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bde5392d299..7176337dbfd 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5843,6 +5843,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, */ if (!select->quick->reverse_sorted()) { + if (table->file->index_flags(ref_key) & HA_NOT_READ_PREFIX_LAST) + DBUG_RETURN(0); // Use filesort // ORDER BY range_key DESC QUICK_SELECT_DESC *tmp=new QUICK_SELECT_DESC(select->quick, used_key_parts); From c96c87d51d4e8e2cc0bee27e1c98cfec830d18a5 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Fri, 4 Jul 2003 16:06:17 -0400 Subject: [PATCH 129/237] fixed bug #670 --- client/mysqlbinlog.cc | 286 +++++++++++++++++++++++++++++++++++++++--- sql/log_event.cc | 31 ++++- sql/log_event.h | 8 ++ 3 files changed, 300 insertions(+), 25 deletions(-) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index b0175103840..ac1c9db30e6 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -18,7 +18,9 @@ #undef MYSQL_SERVER #include "client_priv.h" #include +#include #include "log_event.h" +#include "include/my_sys.h" #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) @@ -49,6 +51,7 @@ static bool short_form = 0; static ulonglong offset = 0; static const char* host = "localhost"; static int port = MYSQL_PORT; +static const char* sock= MYSQL_UNIX_ADDR; static const char* user = "test"; static const char* pass = ""; static ulonglong position = 0; @@ -56,6 +59,8 @@ static bool use_remote = 0; static short binlog_flags = 0; static MYSQL* mysql = NULL; +static const char* dirname_for_local_load= 0; + static void dump_local_log_entries(const char* logname); static void dump_remote_log_entries(const char* logname); static void dump_log_entries(const char* logname); @@ -63,40 +68,170 @@ static void dump_remote_file(NET* net, const char* fname); static void die(const char* fmt, ...); static MYSQL* safe_connect(); +class Load_log_processor +{ + char target_dir_name[MY_NFILE]; + int target_dir_name_len; + DYNAMIC_ARRAY file_names; + + const char* create_file(Create_file_log_event *ce) + { + const char *bname= ce->fname + ce->fname_len -1; + while (bname>ce->fname && bname[-1]!=FN_LIBCHAR) + bname--; + + uint blen= ce->fname_len - (bname-ce->fname); + uint full_len= target_dir_name_len + blen; + char *tmp; + if (!(tmp= my_malloc(full_len + 9 + 1,MYF(MY_WME))) || + set_dynamic(&file_names,(gptr)&ce,ce->file_id)) + { + die("Could not construct local filename %s%s",target_dir_name,bname); + return 0; + } + + char *ptr= tmp; + memcpy(ptr,target_dir_name,target_dir_name_len); + ptr+= target_dir_name_len; + memcpy(ptr,bname,blen); + ptr+= blen; + sprintf(ptr,"-%08x",ce->file_id); + + ce->set_fname_outside_temp_buf(tmp,full_len); + + return tmp; + } + + void append_to_file(const char* fname, int flags, + gptr data, uint size) + { + File file; + if (((file= my_open(fname,flags,MYF(MY_WME))) < 0) || + my_write(file,(byte*) data,size,MYF(MY_WME|MY_NABP)) || + my_close(file,MYF(MY_WME))) + exit(1); + } + +public: + + Load_log_processor() + { + init_dynamic_array(&file_names,sizeof(Create_file_log_event*), + 100,100 CALLER_INFO); + } + + ~Load_log_processor() + { + destroy(); + delete_dynamic(&file_names); + } + + void init_by_dir_name(const char *atarget_dir_name) + { + char *end= strmov(target_dir_name,atarget_dir_name); + if (end[-1]!=FN_LIBCHAR) + *end++= FN_LIBCHAR; + target_dir_name_len= end-target_dir_name; + } + void init_by_file_name(const char *file_name) + { + int len= strlen(file_name); + const char *end= file_name + len - 1; + while (end>file_name && *end!=FN_LIBCHAR) + end--; + if (*end!=FN_LIBCHAR) + target_dir_name_len= 0; + else + { + target_dir_name_len= end - file_name + 1; + memmove(target_dir_name,file_name,target_dir_name_len); + } + } + void init_by_cur_dir() + { + if (my_getwd(target_dir_name,sizeof(target_dir_name),MYF(MY_WME))) + exit(1); + target_dir_name_len= strlen(target_dir_name); + } + void destroy() + { + Create_file_log_event **ptr= (Create_file_log_event**)file_names.buffer; + Create_file_log_event **end= ptr + file_names.elements; + for (; ptrfname,MYF(MY_WME)); + delete *ptr; + *ptr= 0; + } + } + } + Create_file_log_event *grab_event(uint file_id) + { + Create_file_log_event **ptr= + (Create_file_log_event**)file_names.buffer + file_id; + Create_file_log_event *res= *ptr; + *ptr= 0; + return res; + } + void process(Create_file_log_event *ce) + { + const char *fname= create_file(ce); + append_to_file(fname,O_CREAT|O_EXCL|O_BINARY|O_WRONLY,ce->block,ce->block_len); + } + void process(Append_block_log_event *ae) + { + if (ae->file_id >= file_names.elements) + die("Skiped CreateFile event for file_id: %u",ae->file_id); + Create_file_log_event* ce= + *((Create_file_log_event**)file_names.buffer + ae->file_id); + append_to_file(ce->fname,O_APPEND|O_BINARY|O_WRONLY,ae->block,ae->block_len); + } +}; + +Load_log_processor load_processor; + static struct my_option my_long_options[] = { #ifndef DBUG_OFF {"debug", '#', "Output debug log.", (gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"database", 'd', "List entries for just this database (local log only)", + {"database", 'd', "List entries for just this database (local log only).", (gptr*) &database, (gptr*) &database, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"force-read", 'f', "Force reading unknown binlog events", + {"force-read", 'f', "Force reading unknown binlog events.", (gptr*) &force_opt, (gptr*) &force_opt, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"help", '?', "Display this help and exit", + {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"host", 'h', "Get the binlog from server", (gptr*) &host, (gptr*) &host, + {"host", 'h', "Get the binlog from server.", (gptr*) &host, (gptr*) &host, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"offset", 'o', "Skip the first N entries", (gptr*) &offset, (gptr*) &offset, + {"offset", 'o', "Skip the first N entries.", (gptr*) &offset, (gptr*) &offset, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"password", 'p', "Password to connect to remote server", + {"password", 'p', "Password to connect to remote server.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"port", 'P', "Use port to connect to the remote server", + {"port", 'P', "Use port to connect to the remote server.", (gptr*) &port, (gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0}, - {"position", 'j', "Start reading the binlog at position N", + {"position", 'j', "Start reading the binlog at position N.", (gptr*) &position, (gptr*) &position, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"result-file", 'r', "Direct output to a given file", 0, 0, 0, GET_STR, + {"result-file", 'r', "Direct output to a given file.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"short-form", 's', "Just show the queries, no extra info", + {"short-form", 's', "Just show the queries, no extra info.", (gptr*) &short_form, (gptr*) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"user", 'u', "Connect to the remote server as username", + {"socket", 'S', "Socket file to use for connection.", + (gptr*) &sock, (gptr*) &sock, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, + 0, 0}, + {"user", 'u', "Connect to the remote server as username.", (gptr*) &user, (gptr*) &user, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"local-load", 'l', "Prepare files for local load in directory.", + (gptr*) &dirname_for_local_load, (gptr*) &dirname_for_local_load, 0, + GET_STR_ALLOC, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Print version and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} @@ -180,7 +315,7 @@ extern "C" my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) { - switch(optid) { + switch (optid) { #ifndef DBUG_OFF case '#': DBUG_PUSH(argument ? argument : default_dbug_option); @@ -234,7 +369,7 @@ static MYSQL* safe_connect() if(!local_mysql) die("Failed on mysql_init"); - if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, 0, 0)) + if (!mysql_real_connect(local_mysql, host, user, pass, 0, port, sock, 0)) die("failed on connect: %s", mysql_error(local_mysql)); return local_mysql; @@ -346,7 +481,7 @@ static void dump_remote_log_entries(const char* logname) } -static int check_header(IO_CACHE* file, const char *fname) +static int check_header(IO_CACHE* file) { byte header[BIN_LOG_HEADER_SIZE]; byte buf[PROBE_HEADER_LEN]; @@ -357,7 +492,7 @@ static int check_header(IO_CACHE* file, const char *fname) if (my_b_read(file, header, sizeof(header))) die("Failed reading header; Probably an empty file"); if (memcmp(header, BINLOG_MAGIC, sizeof(header))) - die("File %s is not a binary log file",fname); + die("File is not a binary log file"); if (!my_b_read(file, buf, sizeof(buf))) { if (buf[4] == START_EVENT) @@ -390,14 +525,14 @@ static void dump_local_log_entries(const char* logname) if (init_io_cache(file, fd, 0, READ_CACHE, (my_off_t) position, 0, MYF(MY_WME | MY_NABP))) exit(1); - old_format = check_header(file,logname); + old_format = check_header(file); } else { if (init_io_cache(file, fileno(result_file), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) exit(1); - old_format = check_header(file,""); + old_format = check_header(file); if (position) { /* skip 'position' characters from stdout */ @@ -466,17 +601,112 @@ Could not read entry at offset %s : Error in log format or read error", } if (!short_form) fprintf(result_file, "# at %s\n",llstr(old_off,llbuff)); - - ev->print(result_file, short_form, last_db); + + switch (ev->get_type_code()) { + case CREATE_FILE_EVENT: + { + Create_file_log_event* ce= (Create_file_log_event*)ev; + ce->print(result_file, short_form, last_db,true); + load_processor.process(ce); + ev= 0; + break; + } + case APPEND_BLOCK_EVENT: + ev->print(result_file, short_form, last_db); + load_processor.process((Append_block_log_event*)ev); + break; + case EXEC_LOAD_EVENT: + { + ev->print(result_file, short_form, last_db); + Execute_load_log_event *exv= (Execute_load_log_event*)ev; + Create_file_log_event *ce= load_processor.grab_event(exv->file_id); + ce->print(result_file, short_form, last_db,true); + my_free((char*)ce->fname,MYF(MY_WME)); + delete ce; + break; + } + default: + ev->print(result_file, short_form, last_db); + } } rec_count++; - delete ev; + if (ev) + delete ev; } if (fd >= 0) my_close(fd, MYF(MY_WME)); end_io_cache(file); } +#if MYSQL_VERSION_ID < 40101 + +typedef struct st_my_tmpdir +{ + char **list; + uint cur, max; +} MY_TMPDIR; + +#if defined( __WIN__) || defined(OS2) +#define DELIM ';' +#else +#define DELIM ':' +#endif + +my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist) +{ + char *end, *copy; + char buff[FN_REFLEN]; + DYNAMIC_ARRAY t_arr; + if (my_init_dynamic_array(&t_arr, sizeof(char*), 1, 5)) + return TRUE; + if (!pathlist || !pathlist[0]) + { + /* Get default temporary directory */ + pathlist=getenv("TMPDIR"); /* Use this if possible */ +#if defined( __WIN__) || defined(OS2) + if (!pathlist) + pathlist=getenv("TEMP"); + if (!pathlist) + pathlist=getenv("TMP"); +#endif + if (!pathlist || !pathlist[0]) + pathlist=(char*) P_tmpdir; + } + do + { + end=strcend(pathlist, DELIM); + convert_dirname(buff, pathlist, end); + if (!(copy=my_strdup(buff, MYF(MY_WME)))) + return TRUE; + if (insert_dynamic(&t_arr, (gptr)©)) + return TRUE; + pathlist=end+1; + } + while (*end); + freeze_size(&t_arr); + tmpdir->list=(char **)t_arr.buffer; + tmpdir->max=t_arr.elements-1; + tmpdir->cur=0; + return FALSE; +} + +char *my_tmpdir(MY_TMPDIR *tmpdir) +{ + char *dir; + dir=tmpdir->list[tmpdir->cur]; + tmpdir->cur= (tmpdir->cur == tmpdir->max) ? 0 : tmpdir->cur+1; + return dir; +} + +void free_tmpdir(MY_TMPDIR *tmpdir) +{ + uint i; + for (i=0; i<=tmpdir->max; i++) + my_free(tmpdir->list[i], MYF(0)); + my_free((gptr)tmpdir->list, MYF(0)); +} + +#endif int main(int argc, char** argv) { @@ -492,9 +722,25 @@ int main(int argc, char** argv) if (use_remote) mysql = safe_connect(); + MY_TMPDIR tmpdir; + tmpdir.list= 0; + if (!dirname_for_local_load) + { + if (init_tmpdir(&tmpdir, 0)) + exit(1); + dirname_for_local_load= my_tmpdir(&tmpdir); + } + + if (dirname_for_local_load) + load_processor.init_by_dir_name(dirname_for_local_load); + else + load_processor.init_by_cur_dir(); + while (--argc >= 0) dump_log_entries(*(argv++)); + if (tmpdir.list) + free_tmpdir(&tmpdir); if (result_file != stdout) my_fclose(result_file, MYF(0)); if (use_remote) diff --git a/sql/log_event.cc b/sql/log_event.cc index ae4a429e35f..5f3d4263642 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1289,7 +1289,10 @@ void Load_log_event::print(FILE* file, bool short_form, char* last_db) if (db && db[0] && !same_db) fprintf(file, "use %s;\n", db); - fprintf(file, "LOAD DATA INFILE '%-*s' ", fname_len, fname); + fprintf(file, "LOAD DATA "); + if (check_fname_outside_temp_buf()) + fprintf(file, "LOCAL "); + fprintf(file, "INFILE '%-*s' ", fname_len, fname); if (sql_ex.opt_flags & REPLACE_FLAG ) fprintf(file," REPLACE "); @@ -1550,13 +1553,31 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len, #ifdef MYSQL_CLIENT +void Create_file_log_event::print(FILE* file, bool short_form, + char* last_db, bool enable_local) +{ + if (short_form) + { + if (enable_local && check_fname_outside_temp_buf()) + Load_log_event::print(file, 1, last_db); + return; + } + + if (enable_local) + { + if (!check_fname_outside_temp_buf()) + fprintf(file, "#"); + Load_log_event::print(file, 1, last_db); + fprintf(file, "#"); + } + + fprintf(file, " file_id: %d block_len: %d\n", file_id, block_len); +} + void Create_file_log_event::print(FILE* file, bool short_form, char* last_db) { - if (short_form) - return; - Load_log_event::print(file, 1, last_db); - fprintf(file, " file_id: %d block_len: %d\n", file_id, block_len); + print(file,short_form,last_db,0); } #endif diff --git a/sql/log_event.h b/sql/log_event.h index a55efffa319..0a807bd524d 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -404,6 +404,13 @@ public: uint32 skip_lines; sql_ex_info sql_ex; + /* fname doesn't point to memory inside Log_event::temp_buf */ + void set_fname_outside_temp_buf(const char *afname, uint alen) + {fname=afname;fname_len=alen;} + /* fname doesn't point to memory inside Log_event::temp_buf */ + int check_fname_outside_temp_buf() + {return fnametemp_buf+cached_event_len;} + #ifndef MYSQL_CLIENT String field_lens_buf; String fields_buf; @@ -636,6 +643,7 @@ public: int exec_event(struct st_relay_log_info* rli); #else void print(FILE* file, bool short_form = 0, char* last_db = 0); + void print(FILE* file, bool short_form, char* last_db, bool enable_local); #endif Create_file_log_event(const char* buf, int event_len, bool old_format); From a3fe7c0959c6135383409a935d7105812bcaca83 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Fri, 4 Jul 2003 23:06:19 +0300 Subject: [PATCH 130/237] Remove compiler warnings Simple cleanup of previous pull --- sql/item_strfunc.cc | 2 +- sql/log_event.h | 9 +++++++-- sql/sql_cache.cc | 2 +- sql/sql_handler.cc | 2 +- sql/sql_parse.cc | 5 ++++- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index caaff4d1613..801b77ffcce 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1558,7 +1558,7 @@ longlong Item_func_elt::val_int() if ((tmp=(uint) item->val_int()) == 0 || tmp > arg_count) return 0; - int result= args[tmp-1]->val_int(); + longlong result= args[tmp-1]->val_int(); null_value= args[tmp-1]->null_value; return result; } diff --git a/sql/log_event.h b/sql/log_event.h index 0a807bd524d..155da07bebd 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -406,10 +406,15 @@ public: /* fname doesn't point to memory inside Log_event::temp_buf */ void set_fname_outside_temp_buf(const char *afname, uint alen) - {fname=afname;fname_len=alen;} + { + fname= afname; + fname_len= alen; + } /* fname doesn't point to memory inside Log_event::temp_buf */ int check_fname_outside_temp_buf() - {return fnametemp_buf+cached_event_len;} + { + return fname < temp_buf || fname > temp_buf+ cached_event_len; + } #ifndef MYSQL_CLIENT String field_lens_buf; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 1fcd0d1456b..97ec6033ad6 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -744,7 +744,7 @@ void Query_cache::store_query(THD *thd, TABLE_LIST *tables_used) DBUG_VOID_RETURN; if ((local_tables= is_cacheable(thd, thd->query_length, - thd->query, &thd->lex, tables_used))) + thd->query, &thd->lex, tables_used))) { NET *net= &thd->net; byte flags= (thd->client_capabilities & CLIENT_LONG_FLAG ? 0x80 : 0); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index e685ea3a059..b0d8b18dd17 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -234,7 +234,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, } if (cond && !cond->val_int()) continue; - if (!err && num_rows >= offset_limit) + if (num_rows >= offset_limit) { String *packet = &thd->packet; Item *item; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f5ecb98b3be..3c84caff4c5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -501,7 +501,10 @@ check_connections(THD *thd) #if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread) /* Fast local hostname resolve for Win32 */ if (!strcmp(thd->ip,"127.0.0.1")) - thd->host= thd->host_or_ip= (char*) localhost; + { + thd->host= (char*) localhost; + thd->host_or_ip= localhost; + } else #endif if (!(specialflag & SPECIAL_NO_RESOLVE)) From fe025d40c48d28542aa2169f417c8127a737356d Mon Sep 17 00:00:00 2001 From: "jani@rhols221.adsl.netsonic.fi" <> Date: Fri, 4 Jul 2003 23:06:21 +0300 Subject: [PATCH 131/237] Fixed a compatibility bug in mysqlhotcopy between different versions of DBD. New mysqlhotcopy version supports both old and new DBD versions while versions elder than 1.19 support only old DBD versions. --- scripts/mysqlhotcopy.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index a89a8919752..fa35a1c6555 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -37,7 +37,7 @@ WARNING: THIS PROGRAM IS STILL IN BETA. Comments/patches welcome. # Documentation continued at end of file -my $VERSION = "1.18"; +my $VERSION = "1.19"; my $opt_tmpdir = $ENV{TMPDIR} || "/tmp"; @@ -770,6 +770,10 @@ sub quote_names { my ($db, $table, @cruft) = split( /\./, $name ); die "Invalid db.table name '$name'" if (@cruft || !defined $db || !defined $table ); + # Earlier versions of DBD return table name non-quoted, + # such as DBD-2.1012 and the newer ones, such as DBD-2.9002 + # returns it quoted. Let's have a support for both. + $table=~ s/\`//g; return "`$db`.`$table`"; } From ee9237e0d8860fc2b4e67263a2335508ce2e0054 Mon Sep 17 00:00:00 2001 From: "Sinisa@sinisa.nasamreza.org" <> Date: Sat, 5 Jul 2003 16:29:11 +0300 Subject: [PATCH 132/237] missing test case for DISTINCT .. LEFT .. --- mysql-test/r/distinct.result | 9 +++++++++ mysql-test/t/distinct.test | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 53a20eeea0b..1dbccb65748 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -419,3 +419,12 @@ SELECT DISTINCT t1.a, t2.b FROM t1, t2 WHERE t1.a=1 ORDER BY t2.c; a b 1 4 DROP TABLE IF EXISTS t1,t2; +CREATE table t1 ( `id` int(11) NOT NULL auto_increment, `name` varchar(50) NOT NULL default '', PRIMARY KEY (`id`)) TYPE=MyISAM AUTO_INCREMENT=3 ; +INSERT INTO t1 VALUES (1, 'aaaaa'); +INSERT INTO t1 VALUES (3, 'aaaaa'); +INSERT INTO t1 VALUES (2, 'eeeeeee'); +select distinct left(name,1) as name from t1; +name +a +e +drop table t1; diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index ecce2409571..1cc692bd886 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -273,4 +273,11 @@ CREATE TABLE t2 (a int primary key, b int, c int); INSERT t2 VALUES (3,4,5); SELECT DISTINCT t1.a, t2.b FROM t1, t2 WHERE t1.a=1 ORDER BY t2.c; DROP TABLE IF EXISTS t1,t2; +CREATE table t1 ( `id` int(11) NOT NULL auto_increment, `name` varchar(50) NOT NULL default '', PRIMARY KEY (`id`)) TYPE=MyISAM AUTO_INCREMENT=3 ; +INSERT INTO t1 VALUES (1, 'aaaaa'); +INSERT INTO t1 VALUES (3, 'aaaaa'); +INSERT INTO t1 VALUES (2, 'eeeeeee'); +select distinct left(name,1) as name from t1; +drop table t1; + From e387dac04206abfd4164be6c5569d152d2da1a9f Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sun, 6 Jul 2003 16:17:02 +0300 Subject: [PATCH 133/237] srv0srv.c: In background loop run purge to completion before doing other background operations: it does not make sense to flush buffer pool pages if they are soon modified again by purge trx0purge.c: Increase purge_sys->n_pages_handled for every undo log we purge, even if that log would be only a hundred bytes: that way we get the purge batches of 20 pages to set a fresh purge view (limit) more often, and we can reduce the number of old row versions purge has to look at when it decides if it can remove some delete-marked index record --- innobase/srv/srv0srv.c | 27 +++++++++++++++++++++++---- innobase/trx/trx0purge.c | 13 +++---------- 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 083cbfd2609..a2314cde2dd 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -3009,10 +3009,29 @@ background_loop: srv_main_thread_op_info = (char*)"purging"; - if (srv_fast_shutdown && srv_shutdown_state > 0) { - n_pages_purged = 0; - } else { - n_pages_purged = trx_purge(); + /* Run a full purge */ + + n_pages_purged = 1; + + last_flush_time = time(NULL); + + while (n_pages_purged) { + if (srv_fast_shutdown && srv_shutdown_state > 0) { + + break; + } + + srv_main_thread_op_info = (char*)"purging"; + n_pages_purged = trx_purge(); + + current_time = time(NULL); + + if (difftime(current_time, last_flush_time) > 1) { + srv_main_thread_op_info = (char*) "flushing log"; + + log_buffer_flush_to_disk(); + last_flush_time = current_time; + } } srv_main_thread_op_info = (char*)"reserving kernel mutex"; diff --git a/innobase/trx/trx0purge.c b/innobase/trx/trx0purge.c index d58240d3c11..fa9c287b0ad 100644 --- a/innobase/trx/trx0purge.c +++ b/innobase/trx/trx0purge.c @@ -593,7 +593,7 @@ trx_purge_rseg_get_next_history_log( mutex_enter(&(rseg->mutex)); - ut_ad(rseg->last_page_no != FIL_NULL); + ut_a(rseg->last_page_no != FIL_NULL); purge_sys->purge_trx_no = ut_dulint_add(rseg->last_trx_no, 1); purge_sys->purge_undo_no = ut_dulint_zero; @@ -606,16 +606,9 @@ trx_purge_rseg_get_next_history_log( log_hdr = undo_page + rseg->last_offset; seg_hdr = undo_page + TRX_UNDO_SEG_HDR; - if ((mach_read_from_2(log_hdr + TRX_UNDO_NEXT_LOG) == 0) - && (mach_read_from_2(seg_hdr + TRX_UNDO_STATE) - == TRX_UNDO_TO_PURGE)) { - - /* This is the last log header on this page and the log - segment cannot be reused: we may increment the number of - pages handled */ + /* Increase the purge page count by one for every handled log */ - purge_sys->n_pages_handled++; - } + purge_sys->n_pages_handled++; prev_log_addr = trx_purge_get_log_from_hist( flst_get_prev_addr(log_hdr + TRX_UNDO_HISTORY_NODE, From 7be1beb2d39db12d192110325958fd820c1fff8f Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sun, 6 Jul 2003 18:01:51 +0300 Subject: [PATCH 134/237] row0mysql.c: Fix performance bug: if there were thousands of tables, DROP TABLE could take as much as a second CPU time --- innobase/row/row0mysql.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index af73c2f62c3..51231de4d77 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1937,7 +1937,8 @@ row_drop_table_for_mysql( " found := 0;\n" " ELSE" " DELETE FROM SYS_FIELDS WHERE INDEX_ID = index_id;\n" - " DELETE FROM SYS_INDEXES WHERE ID = index_id;\n" + " DELETE FROM SYS_INDEXES WHERE ID = index_id\n" + " AND TABLE_ID = table_id;\n" " END IF;\n" "END LOOP;\n" "DELETE FROM SYS_COLUMNS WHERE TABLE_ID = table_id;\n" From 9c73d91d540f094765e9cdea27f0011e7afca518 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sun, 6 Jul 2003 17:59:54 +0200 Subject: [PATCH 135/237] WL#912 (more user control on relay logs): FLUSH LOGS now rotates relay logs, and a new variable max_relay_log_size. Plus a very small bit of code cleaning. --- libmysqld/lib_sql.cc | 8 +-- mysql-test/r/rpl_flush_log_loop.result | 2 +- mysql-test/r/rpl_log.result | 2 +- mysql-test/r/rpl_max_relay_size.result | 61 +++++++++++++++++++ mysql-test/r/rpl_rotate_logs.result | 6 +- mysql-test/t/rpl_max_relay_size.test | 81 +++++++++++++++++++++++++ mysql-test/t/rpl_rotate_logs-master.opt | 2 +- sql/log.cc | 72 +++++++++++++++++----- sql/mysql_priv.h | 7 ++- sql/mysqld.cc | 30 +++++---- sql/set_var.cc | 30 ++++++++- sql/slave.cc | 52 +++++++++++++++- sql/slave.h | 1 + sql/sql_class.h | 18 +++++- sql/sql_parse.cc | 8 +++ 15 files changed, 335 insertions(+), 45 deletions(-) create mode 100644 mysql-test/r/rpl_max_relay_size.result create mode 100644 mysql-test/t/rpl_max_relay_size.test diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 7682d60d991..eddb326f6c4 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -511,17 +511,17 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) /* Setup log files */ if (opt_log) open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS, - LOG_NORMAL); + LOG_NORMAL, 0, 0, 0); if (opt_update_log) { open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", - NullS, LOG_NEW); + NullS, LOG_NEW, 0, 0, 0); using_update_log=1; } if (opt_slow_log) open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", - NullS, LOG_NORMAL); + NullS, LOG_NORMAL, 0, 0, 0); if (ha_init()) { sql_print_error("Can't init databases"); @@ -586,7 +586,7 @@ int STDCALL mysql_server_init(int argc, char **argv, char **groups) opt_bin_logname=my_strdup(tmp,MYF(MY_WME)); } open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", - opt_binlog_index_name, LOG_BIN); + opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size); using_update_log=1; } diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flush_log_loop.result index da2930f30c3..3273ce43a17 100644 --- a/mysql-test/r/rpl_flush_log_loop.result +++ b/mysql-test/r/rpl_flush_log_loop.result @@ -14,4 +14,4 @@ slave start; flush logs; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root SLAVE_PORT 60 slave-bin.001 79 relay-log.001 119 slave-bin.001 Yes Yes 0 0 79 119 +127.0.0.1 root SLAVE_PORT 60 slave-bin.001 79 relay-log.002 119 slave-bin.001 Yes Yes 0 0 79 119 diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 616ad319880..640e6f02103 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -93,6 +93,6 @@ slave-bin.002 62 Query 1 168 use test; insert into t1 values (1) slave-bin.002 122 Query 1 228 use test; drop table t1 show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.002 1563 master-bin.002 Yes Yes 0 0 276 1563 +127.0.0.1 root MASTER_PORT 1 master-bin.002 276 slave-relay-bin.003 211 master-bin.002 Yes Yes 0 0 276 211 show binlog events in 'slave-bin.005' from 4; Error when executing command SHOW BINLOG EVENTS: Could not find target log diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result new file mode 100644 index 00000000000..5c5a9d622e5 --- /dev/null +++ b/mysql-test/r/rpl_max_relay_size.result @@ -0,0 +1,61 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +stop slave; +create table t1 (a int); +drop table t1; +reset slave; +set global max_binlog_size=8192; +set global max_relay_log_size=8192-1; +select @@global.max_relay_log_size; +@@global.max_relay_log_size +4096 +start slave; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.014 1221 master-bin.001 Yes Yes 0 0 50477 1221 +stop slave; +reset slave; +set global max_relay_log_size=(5*4096); +select @@global.max_relay_log_size; +@@global.max_relay_log_size +20480 +start slave; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 9457 +stop slave; +reset slave; +set global max_relay_log_size=0; +select @@global.max_relay_log_size; +@@global.max_relay_log_size +0 +start slave; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.008 1283 master-bin.001 Yes Yes 0 0 50477 1283 +stop slave; +reset slave; +flush logs; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9306 1 4 slave-relay-bin.001 4 No No 0 0 0 4 +reset slave; +start slave; +flush logs; +create table t1 (a int); +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50535 slave-relay-bin.009 62 master-bin.001 Yes Yes 0 0 50535 62 +flush logs; +drop table t1; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 50583 slave-relay-bin.010 52 master-bin.001 Yes Yes 0 0 50583 52 +flush logs; +show master status; +File Position Binlog_do_db Binlog_ignore_db +master-bin.002 4 diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index f49006e8e05..07490744d81 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -65,17 +65,15 @@ show master logs; Log_name master-bin.003 master-bin.004 -master-bin.005 -master-bin.006 show master status; File Position Binlog_do_db Binlog_ignore_db -master-bin.006 838 +master-bin.004 2886 select * from t4; a testing temporary tables part 2 show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 60 master-bin.006 838 slave-relay-bin.001 8034 master-bin.006 Yes Yes 0 0 838 8034 +127.0.0.1 root MASTER_PORT 60 master-bin.004 2886 slave-relay-bin.001 7870 master-bin.004 Yes Yes 0 0 2886 7870 lock tables t3 read; select count(*) from t3 where n >= 4; count(*) diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test new file mode 100644 index 00000000000..4befe4024fc --- /dev/null +++ b/mysql-test/t/rpl_max_relay_size.test @@ -0,0 +1,81 @@ +# Test of options max_binlog_size and max_relay_log_size and +# how they act (if max_relay_log_size == 0, use max_binlog_size +# for relay logs too). +# Test of manual relay log rotation with FLUSH LOGS. + +source include/master-slave.inc; +connection slave; +stop slave; +connection master; +# Generate a big enough master's binlog to cause relay log rotations +create table t1 (a int); +let $1=800; +disable_query_log; +begin; +while ($1) +{ +# eval means expand $ expressions + eval insert into t1 values( $1 ); + dec $1; +} +enable_query_log; +drop table t1; +save_master_pos; +connection slave; +reset slave; +set global max_binlog_size=8192; +set global max_relay_log_size=8192-1; # mapped to 4096 +select @@global.max_relay_log_size; +start slave; +sync_with_master; +show slave status; +stop slave; +reset slave; +set global max_relay_log_size=(5*4096); +select @@global.max_relay_log_size; +start slave; +sync_with_master; +show slave status; +stop slave; +reset slave; +set global max_relay_log_size=0; +select @@global.max_relay_log_size; +start slave; +sync_with_master; +show slave status; + +# Tests below are mainly to ensure that we have not coded with wrong assumptions + +stop slave; +reset slave; +# test of relay log rotation when the slave is stopped +# (to make sure it does not crash). +flush logs; +show slave status; + +reset slave; +start slave; +sync_with_master; +# test of relay log rotation when the slave is started +flush logs; +# We have now easy way to be sure that the SQL thread has now deleted the +# log we just closed. But a trick to achieve this is do an update on the master. +connection master; +create table t1 (a int); +save_master_pos; +connection slave; +sync_with_master; +show slave status; +# one more rotation, to be sure Relay_log_space is correctly updated +flush logs; +connection master; +drop table t1; +save_master_pos; +connection slave; +sync_with_master; +show slave status; + +connection master; +# test that the absence of relay logs does not make a master crash +flush logs; +show master status; diff --git a/mysql-test/t/rpl_rotate_logs-master.opt b/mysql-test/t/rpl_rotate_logs-master.opt index f27601e0d7d..ad2c6a647b5 100644 --- a/mysql-test/t/rpl_rotate_logs-master.opt +++ b/mysql-test/t/rpl_rotate_logs-master.opt @@ -1 +1 @@ --O max_binlog_size=2048 +-O max_binlog_size=4096 diff --git a/sql/log.cc b/sql/log.cc index 99bc6ee32b4..ef7cdd0dbd5 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -133,11 +133,15 @@ int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) void MYSQL_LOG::init(enum_log_type log_type_arg, enum cache_type io_cache_type_arg, - bool no_auto_events_arg) + bool no_auto_events_arg, + ulong max_size_arg) { + DBUG_ENTER("MYSQL_LOG::init"); log_type = log_type_arg; io_cache_type = io_cache_type_arg; no_auto_events = no_auto_events_arg; + max_size=max_size_arg; + DBUG_PRINT("info",("log_type=%d max_size=%lu", log_type, max_size)); if (!inited) { inited= 1; @@ -145,6 +149,7 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW); (void) pthread_cond_init(&update_cond, 0); } + DBUG_VOID_RETURN; } @@ -165,7 +170,8 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, const char *new_name, const char *index_file_name_arg, enum cache_type io_cache_type_arg, - bool no_auto_events_arg) + bool no_auto_events_arg, + ulong max_size) { char buff[512]; File file= -1, index_file_nr= -1; @@ -178,7 +184,7 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name)) no_rotate = 1; - init(log_type_arg,io_cache_type_arg,no_auto_events_arg); + init(log_type_arg,io_cache_type_arg,no_auto_events_arg,max_size); if (!(name=my_strdup(log_name,MYF(MY_WME)))) goto err; @@ -577,7 +583,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) if (!thd->slave_thread) need_start_event=1; open(save_name, save_log_type, 0, index_file_name, - io_cache_type, no_auto_events); + io_cache_type, no_auto_events, max_size); my_free((gptr) save_name, MYF(0)); err: @@ -802,8 +808,12 @@ void MYSQL_LOG::new_file(bool need_lock) char new_name[FN_REFLEN], *new_name_ptr, *old_name; enum_log_type save_log_type; + DBUG_ENTER("MYSQL_LOG::new_file"); if (!is_open()) - return; // Should never happen + { + DBUG_PRINT("info",("log is closed")); + DBUG_VOID_RETURN; + } if (need_lock) { @@ -865,8 +875,16 @@ void MYSQL_LOG::new_file(bool need_lock) save_log_type=log_type; name=0; // Don't free name close(); +/* + if (save_log_type == LOG_BIN) + { + printf("after close, before open; I wait for 20 seconds\n"); + sleep(20); + printf("sleep finished, opening\n"); + } +*/ open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type, - no_auto_events); + no_auto_events, max_size); my_free(old_name,MYF(0)); end: @@ -875,6 +893,7 @@ end: pthread_mutex_unlock(&LOCK_index); pthread_mutex_unlock(&LOCK_log); } + DBUG_VOID_RETURN; } @@ -882,7 +901,8 @@ bool MYSQL_LOG::append(Log_event* ev) { bool error = 0; pthread_mutex_lock(&LOCK_log); - + DBUG_ENTER("MYSQL_LOG::append"); + DBUG_ASSERT(log_file.type == SEQ_READ_APPEND); /* Log_event::write() is smart enough to use my_b_write() or @@ -894,7 +914,8 @@ bool MYSQL_LOG::append(Log_event* ev) goto err; } bytes_written += ev->get_event_len(); - if ((uint) my_b_append_tell(&log_file) > max_binlog_size) + DBUG_PRINT("info",("max_size=%lu",max_size)); + if ((uint) my_b_append_tell(&log_file) > max_size) { pthread_mutex_lock(&LOCK_index); new_file(0); @@ -904,13 +925,14 @@ bool MYSQL_LOG::append(Log_event* ev) err: pthread_mutex_unlock(&LOCK_log); signal_update(); // Safe as we don't call close - return error; + DBUG_RETURN(error); } bool MYSQL_LOG::appendv(const char* buf, uint len,...) { bool error= 0; + DBUG_ENTER("MYSQL_LOG::appendv"); va_list(args); va_start(args,len); @@ -926,8 +948,8 @@ bool MYSQL_LOG::appendv(const char* buf, uint len,...) } bytes_written += len; } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint))); - - if ((uint) my_b_append_tell(&log_file) > max_binlog_size) + DBUG_PRINT("info",("max_size=%lu",max_size)); + if ((uint) my_b_append_tell(&log_file) > max_size) { pthread_mutex_lock(&LOCK_index); new_file(0); @@ -938,7 +960,7 @@ err: pthread_mutex_unlock(&LOCK_log); if (!error) signal_update(); - return error; + DBUG_RETURN(error); } @@ -1188,8 +1210,9 @@ bool MYSQL_LOG::write(Log_event* event_info) called_handler_commit=1; } } - /* we wrote to the real log, check automatic rotation */ - should_rotate= (my_b_tell(file) >= (my_off_t) max_binlog_size); + /* We wrote to the real log, check automatic rotation; */ + DBUG_PRINT("info",("max_size=%lu",max_size)); + should_rotate= (my_b_tell(file) >= (my_off_t) max_size); } error=0; @@ -1319,7 +1342,8 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache) log_file.pos_in_file))) goto err; signal_update(); - if (my_b_tell(&log_file) >= (my_off_t) max_binlog_size) + DBUG_PRINT("info",("max_size=%lu",max_size)); + if (my_b_tell(&log_file) >= (my_off_t) max_size) { pthread_mutex_lock(&LOCK_index); new_file(0); // inside mutex @@ -1563,6 +1587,24 @@ void MYSQL_LOG::close(bool exiting) DBUG_VOID_RETURN; } +void MYSQL_LOG::set_max_size(ulong max_size_arg) +{ + /* + We need to take locks, otherwise this may happen: + new_file() is called, calls open(old_max_size), then before open() starts, + set_max_size() sets max_size to max_size_arg, then open() starts and + uses the old_max_size argument, so max_size_arg has been overwritten and + it's like if the SET command was never run. + */ + if (is_open()) + { + pthread_mutex_lock(&LOCK_log); + pthread_mutex_lock(&LOCK_index); + max_size= max_size_arg; + pthread_mutex_unlock(&LOCK_index); + pthread_mutex_unlock(&LOCK_log); + } +} /* Check if a string is a valid number diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 702db98748a..723df948e1d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -606,8 +606,8 @@ bool fn_format_relative_to_data_home(my_string to, const char *name, bool open_log(MYSQL_LOG *log, const char *hostname, const char *opt_name, const char *extension, const char *index_file_name, - enum_log_type type, bool read_append = 0, - bool no_auto_events = 0); + enum_log_type type, bool read_append, + bool no_auto_events, ulong max_size); /* mysqld.cc */ void clear_error_message(THD *thd); @@ -654,7 +654,8 @@ extern ulong max_insert_delayed_threads, max_user_connections; extern ulong long_query_count, what_to_log,flush_time,opt_sql_mode; extern ulong query_buff_size, thread_stack,thread_stack_min; extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit; -extern ulong max_binlog_size, rpl_recovery_rank, thread_cache_size; +extern ulong max_binlog_size, max_relay_log_size; +extern ulong rpl_recovery_rank, thread_cache_size; extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log; extern ulong specialflag, current_pid; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4f6f55bce0b..c45b3184f16 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -354,7 +354,7 @@ ulong table_cache_size, query_buff_size, slow_launch_time = 2L, slave_open_temp_tables=0, - open_files_limit=0, max_binlog_size; + open_files_limit=0, max_binlog_size, max_relay_log_size; ulong com_stat[(uint) SQLCOM_END], com_other; ulong slave_net_timeout; ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0; @@ -1950,7 +1950,7 @@ bool open_log(MYSQL_LOG *log, const char *hostname, const char *opt_name, const char *extension, const char *index_file_name, enum_log_type type, bool read_append, - bool no_auto_events) + bool no_auto_events, ulong max_size) { char tmp[FN_REFLEN]; if (!opt_name || !opt_name[0]) @@ -1976,7 +1976,7 @@ bool open_log(MYSQL_LOG *log, const char *hostname, } return log->open(opt_name, type, 0, index_file_name, (read_append) ? SEQ_READ_APPEND : WRITE_CACHE, - no_auto_events); + no_auto_events, max_size); } @@ -2196,17 +2196,17 @@ int main(int argc, char **argv) /* Setup log files */ if (opt_log) open_log(&mysql_log, glob_hostname, opt_logname, ".log", NullS, - LOG_NORMAL); + LOG_NORMAL, 0, 0, 0); if (opt_update_log) { open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", - NullS, LOG_NEW); + NullS, LOG_NEW, 0, 0, 0); using_update_log=1; } if (opt_slow_log) open_log(&mysql_slow_log, glob_hostname, opt_slow_logname, "-slow.log", - NullS, LOG_NORMAL); + NullS, LOG_NORMAL, 0, 0, 0); if (opt_error_log) { @@ -2321,7 +2321,7 @@ The server will not act as a slave."); if (opt_bin_log) { open_log(&mysql_bin_log, glob_hostname, opt_bin_logname, "-bin", - opt_binlog_index_name,LOG_BIN); + opt_binlog_index_name, LOG_BIN, 0, 0, max_binlog_size); using_update_log=1; } else if (opt_log_slave_updates) @@ -3156,8 +3156,8 @@ enum options { OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE, OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS, OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE, - OPT_MAX_JOIN_SIZE, OPT_MAX_SORT_LENGTH, OPT_MAX_SEEKS_FOR_KEY, - OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, + OPT_MAX_JOIN_SIZE, OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH, + OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE, OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE, @@ -3809,9 +3809,11 @@ replicating a LOAD DATA INFILE command", (gptr*) &max_binlog_cache_size, (gptr*) &max_binlog_cache_size, 0, GET_ULONG, REQUIRED_ARG, ~0L, IO_SIZE, ~0L, 0, IO_SIZE, 0}, {"max_binlog_size", OPT_MAX_BINLOG_SIZE, - "Binary log will be rotated automatically when the size crosses the limit.", + "Binary log will be rotated automatically when the size exceeds this \ +value. Will also apply to relay logs if max_relay_log_size is 0. \ +The minimum value for this variable is 4096.", (gptr*) &max_binlog_size, (gptr*) &max_binlog_size, 0, GET_ULONG, - REQUIRED_ARG, 1024*1024L*1024L, 1024, 1024*1024L*1024L, 0, 1, 0}, + REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0}, {"max_connections", OPT_MAX_CONNECTIONS, "The number of simultaneous clients allowed.", (gptr*) &max_connections, (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1, @@ -3834,6 +3836,12 @@ replicating a LOAD DATA INFILE command", (gptr*) &global_system_variables.max_join_size, (gptr*) &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, + {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE, + "If non-zero: relay log will be rotated automatically when the size exceeds \ +this value; if zero (the default): when the size exceeds max_binlog_size. \ +0 expected, the minimum value for this variable is 4096.", + (gptr*) &max_relay_log_size, (gptr*) &max_relay_log_size, 0, GET_ULONG, + REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0}, { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY, "Limit assumed max number of seeks when looking up rows based on a key", (gptr*) &global_system_variables.max_seeks_for_key, diff --git a/sql/set_var.cc b/sql/set_var.cc index b66c410c6d5..b3238d1c0ec 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -84,6 +84,8 @@ static void fix_query_cache_size(THD *thd, enum_var_type type); static void fix_key_buffer_size(THD *thd, enum_var_type type); static void fix_myisam_max_extra_sort_file_size(THD *thd, enum_var_type type); static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type); +static void fix_max_binlog_size(THD *thd, enum_var_type type); +static void fix_max_relay_log_size(THD *thd, enum_var_type type); /* Variable definition list @@ -142,7 +144,8 @@ sys_var_thd_ulong sys_max_allowed_packet("max_allowed_packet", sys_var_long_ptr sys_max_binlog_cache_size("max_binlog_cache_size", &max_binlog_cache_size); sys_var_long_ptr sys_max_binlog_size("max_binlog_size", - &max_binlog_size); + &max_binlog_size, + fix_max_binlog_size); sys_var_long_ptr sys_max_connections("max_connections", &max_connections); sys_var_long_ptr sys_max_connect_errors("max_connect_errors", @@ -161,6 +164,9 @@ sys_var_thd_ha_rows sys_sql_max_join_size("sql_max_join_size", &SV::max_join_size, fix_max_join_size); #endif +sys_var_long_ptr sys_max_relay_log_size("max_relay_log_size", + &max_relay_log_size, + fix_max_relay_log_size); sys_var_thd_ulong sys_max_sort_length("max_sort_length", &SV::max_sort_length); sys_var_long_ptr sys_max_user_connections("max_user_connections", @@ -350,6 +356,7 @@ sys_var *sys_variables[]= &sys_max_delayed_threads, &sys_max_heap_table_size, &sys_max_join_size, + &sys_max_relay_log_size, &sys_max_seeks_for_key, &sys_max_sort_length, &sys_max_tmp_tables, @@ -495,6 +502,7 @@ struct show_var_st init_vars[]= { {sys_max_delayed_threads.name,(char*) &sys_max_delayed_threads, SHOW_SYS}, {sys_max_heap_table_size.name,(char*) &sys_max_heap_table_size, SHOW_SYS}, {sys_max_join_size.name, (char*) &sys_max_join_size, SHOW_SYS}, + {sys_max_relay_log_size.name, (char*) &sys_max_relay_log_size, SHOW_SYS}, {sys_max_seeks_for_key.name, (char*) &sys_max_seeks_for_key, SHOW_SYS}, {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS}, {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS}, @@ -697,6 +705,26 @@ void fix_delay_key_write(THD *thd, enum_var_type type) } } +void fix_max_binlog_size(THD *thd, enum_var_type type) +{ + DBUG_ENTER("fix_max_binlog_size"); + DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", + max_binlog_size, max_relay_log_size)); + mysql_bin_log.set_max_size(max_binlog_size); + if (!max_relay_log_size) + active_mi->rli.relay_log.set_max_size(max_binlog_size); + DBUG_VOID_RETURN; +} + +void fix_max_relay_log_size(THD *thd, enum_var_type type) +{ + DBUG_ENTER("fix_max_relay_log_size"); + DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", + max_binlog_size, max_relay_log_size)); + active_mi->rli.relay_log.set_max_size(max_relay_log_size ? + max_relay_log_size: max_binlog_size); + DBUG_VOID_RETURN; +} bool sys_var_long_ptr::update(THD *thd, set_var *var) { diff --git a/sql/slave.cc b/sql/slave.cc index aa9dd14b1c7..f004ed538b0 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1235,7 +1235,17 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname, "-relay-bin", opt_relaylog_index_name, LOG_BIN, 1 /* read_append cache */, - 1 /* no auto events */)) + 1 /* no auto events */, + /* + For the maximum size, we choose max_relay_log_size if it is + non-zero, max_binlog_size otherwise. If later the user does SET + GLOBAL on one of these variables, fix_max_binlog_size and + fix_max_relay_log_size will reconsider the choice (for example + if the user changes max_relay_log_size to zero, we have to + switch to using max_binlog_size for the relay log) and update + rli->relay_log.max_size (and mysql_bin_log.max_size). + */ + max_relay_log_size ? max_relay_log_size : max_binlog_size)) { sql_print_error("Failed in open_log() called from init_relay_log_info()"); DBUG_RETURN(1); @@ -3421,6 +3431,46 @@ err: DBUG_RETURN(0); } +/* + Rotate a relay log (this is used only by FLUSH LOGS; the automatic rotation + because of size is simpler because when we do it we already have all relevant + locks; here we don't, so this function is mainly taking locks). + Returns nothing as we cannot catch any error (MYSQL_LOG::new_file() is void). +*/ + +void rotate_relay_log(MASTER_INFO* mi) +{ + DBUG_ENTER("rotate_relay_log"); + RELAY_LOG_INFO* rli= &mi->rli; + /* If this server is not a slave (or RESET SLAVE has just been run) */ + if (!rli->inited) + { + DBUG_PRINT("info", ("rli->inited=0")); + DBUG_VOID_RETURN; + } + lock_slave_threads(mi); + pthread_mutex_lock(&rli->data_lock); + /* If the relay log is closed, new_file() will do nothing. */ + rli->relay_log.new_file(1); + /* + We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately + be counted, so imagine a succession of FLUSH LOGS and assume the slave + threads are started: + relay_log_space decreases by the size of the deleted relay log, but does not + increase, so flush-after-flush we may become negative, which is wrong. + Even if this will be corrected as soon as a query is replicated on the slave + (because the I/O thread will then call harvest_bytes_written() which will + harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange output + in SHOW SLAVE STATUS meanwhile. So we harvest now. + If the log is closed, then this will just harvest the last writes, probably + 0 as they probably have been harvested. + */ + rli->relay_log.harvest_bytes_written(&rli->log_space_total); + pthread_mutex_unlock(&rli->data_lock); + unlock_slave_threads(mi); + DBUG_VOID_RETURN; +} + #ifdef __GNUC__ template class I_List_iterator; diff --git a/sql/slave.h b/sql/slave.h index 6a73c86d304..aedb21757f8 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -403,6 +403,7 @@ int init_relay_log_pos(RELAY_LOG_INFO* rli,const char* log,ulonglong pos, int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset, const char** errmsg); +void rotate_relay_log(MASTER_INFO* mi); extern "C" pthread_handler_decl(handle_slave_io,arg); extern "C" pthread_handler_decl(handle_slave_sql,arg); diff --git a/sql/sql_class.h b/sql/sql_class.h index d1b2ef82ccb..71b943b5d26 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -84,6 +84,17 @@ class MYSQL_LOG { bool no_rotate; bool need_start_event; bool no_auto_events; // for relay binlog + /* + The max size before rotation (usable only if log_type == LOG_BIN: binary + logs and relay logs). + For a binlog, max_size should be max_binlog_size. + For a relay log, it should be max_relay_log_size if this is non-zero, + max_binlog_size otherwise. + max_size is set in init(), and dynamically changed (when one does SET + GLOBAL MAX_BINLOG_SIZE|MAX_RELAY_LOG_SIZE) by fix_max_binlog_size and + fix_max_relay_log_size). + */ + ulong max_size; friend class Log_event; public: @@ -105,17 +116,18 @@ public: bytes_written=0; DBUG_VOID_RETURN; } + void set_max_size(ulong max_size_arg); void signal_update() { pthread_cond_broadcast(&update_cond);} void wait_for_update(THD* thd); void set_need_start_event() { need_start_event = 1; } void init(enum_log_type log_type_arg, - enum cache_type io_cache_type_arg = WRITE_CACHE, - bool no_auto_events_arg = 0); + enum cache_type io_cache_type_arg, + bool no_auto_events_arg, ulong max_size); void cleanup(); bool open(const char *log_name,enum_log_type log_type, const char *new_name, const char *index_file_name_arg, enum cache_type io_cache_type_arg, - bool no_auto_events_arg); + bool no_auto_events_arg, ulong max_size); void new_file(bool need_lock= 1); bool write(THD *thd, enum enum_server_command command, const char *format,...); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c5b08c6121a..b8ac230f828 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3571,10 +3571,18 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) } if (options & REFRESH_LOG) { + /* + Flush the normal query log, the update log, the binary log, the slow query + log, and the relay log (if it exists). + */ mysql_log.new_file(1); mysql_update_log.new_file(1); mysql_bin_log.new_file(1); mysql_slow_log.new_file(1); + LOCK_ACTIVE_MI; + rotate_relay_log(active_mi); + UNLOCK_ACTIVE_MI; + if (ha_flush_logs()) result=1; if (flush_error_log()) From ea8ed30f03fcf99de0578b76310bc970b06ef1ef Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Mon, 7 Jul 2003 16:39:53 +0300 Subject: [PATCH 136/237] sql_delete.cc: Fix bug: if a DELETE failed in a FOREIGN KEY error and it had already deleted some rows, then MySQL did not roll back the failed SQL statement, and also wrote it to the binlog --- sql/sql_delete.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index caa1e0e0312..96638617610 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -145,7 +145,12 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, else { table->file->print_error(error,MYF(0)); - error=0; + error=1; /* In < 4.0.14 we set the error number to 0 here, but that + was not sensible, because then MySQL would not roll back the + failed DELETE, and also wrote it to the binlog. For MyISAM + tables a DELETE probably never should fail (?), but for + InnoDB it can fail in a FOREIGN KEY error or an + out-of-tablespace error. (Comment by Heikki July 7, 2003) */ break; } } From ec1aca5c52c7e861833b7ee432849757991b6a13 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 7 Jul 2003 16:45:19 +0200 Subject: [PATCH 137/237] correct (finally) condition for MATCH >0, >=0 etc in add_ft_keys (SW#1647) still no rec. descent --- sql/sql_select.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 7176337dbfd..55f10ab930b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1655,17 +1655,17 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, { Item_func *arg0=(Item_func *)(func->arguments()[0]), *arg1=(Item_func *)(func->arguments()[1]); - if ((functype == Item_func::GE_FUNC || - functype == Item_func::GT_FUNC) && - arg0->type() == Item::FUNC_ITEM && - arg0->functype() == Item_func::FT_FUNC && - arg1->const_item() && arg1->val()>0) + if (arg1->const_item() && + ((functype == Item_func::GE_FUNC && arg1->val()> 0) || + (functype == Item_func::GT_FUNC && arg1->val()>=0)) && + arg0->type() == Item::FUNC_ITEM && + arg0->functype() == Item_func::FT_FUNC) cond_func=(Item_func_match *) arg0; - else if ((functype == Item_func::LE_FUNC || - functype == Item_func::LT_FUNC) && + else if (arg0->const_item() && + ((functype == Item_func::LE_FUNC && arg0->val()> 0) || + (functype == Item_func::LT_FUNC && arg0->val()>=0)) && arg1->type() == Item::FUNC_ITEM && - arg1->functype() == Item_func::FT_FUNC && - arg0->const_item() && arg0->val()>0) + arg1->functype() == Item_func::FT_FUNC) cond_func=(Item_func_match *) arg1; } } From bbe08e4a031e3b0fae834e8c2f287231fe6d7e88 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 7 Jul 2003 19:02:58 +0200 Subject: [PATCH 138/237] finally proper recursive descent for parsing expressions with MATCH ... AGAINST in add_ft_keys() --- mysql-test/r/fulltext.result | 43 +++++++++++++++++++++++++++++------- mysql-test/t/fulltext.test | 22 ++++++++++++++---- sql/sql_select.cc | 20 +++-------------- 3 files changed, 56 insertions(+), 29 deletions(-) diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 6f15b2eb973..646c1a7bee2 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -5,9 +5,6 @@ INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'), ('Only MyISAM tables','support collections'), ('Function MATCH ... AGAINST()','is used to do a search'), ('Full-text search in MySQL', 'implements vector space model'); -explain select * from t1 where MATCH(a,b) AGAINST ("collections"); -table type possible_keys key key_len ref rows Extra -t1 fulltext a a 0 1 Using where select * from t1 where MATCH(a,b) AGAINST ("collections"); a b Only MyISAM tables support collections @@ -19,11 +16,36 @@ select * from t1 where MATCH(a,b) AGAINST ("indexes collections"); a b Full-text indexes are called collections Only MyISAM tables support collections -select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes"); -a b -Only MyISAM tables support collections -Full-text indexes are called collections -Full-text indexes are called collections +explain select * from t1 where MATCH(a,b) AGAINST ("collections"); +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0; +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>1; +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=0; +table type possible_keys key key_len ref rows Extra +t1 ALL NULL NULL NULL NULL 5 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=1; +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where +explain select * from t1 where 00 and a like '%ll%'; +table type possible_keys key key_len ref rows Extra +t1 fulltext a a 0 1 Using where select * from t1 where MATCH(a,b) AGAINST("support -collections" IN BOOLEAN MODE); a b MySQL has now support for full-text search @@ -98,6 +120,11 @@ select * from t1 where MATCH b AGAINST ("sear*" IN BOOLEAN MODE); a b MySQL has now support for full-text search Function MATCH ... AGAINST() is used to do a search +select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes"); +a b +Only MyISAM tables support collections +Full-text indexes are called collections +Full-text indexes are called collections delete from t1 where a like "MySQL%"; update t1 set a='some test foobar' where MATCH a,b AGAINST ('model'); delete from t1 where MATCH(a,b) AGAINST ("indexes"); diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 1b85f5903df..942552f5e98 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -12,14 +12,24 @@ INSERT INTO t1 VALUES('MySQL has now support', 'for full-text search'), ('Full-text search in MySQL', 'implements vector space model'); # nl search - -explain select * from t1 where MATCH(a,b) AGAINST ("collections"); + select * from t1 where MATCH(a,b) AGAINST ("collections"); select * from t1 where MATCH(a,b) AGAINST ("indexes"); select * from t1 where MATCH(a,b) AGAINST ("indexes collections"); -# UNION of fulltext's -select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes"); + +# add_ft_keys() tests + +explain select * from t1 where MATCH(a,b) AGAINST ("collections"); +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0; +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>1; +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=0; +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=1; +explain select * from t1 where 00 and a like '%ll%'; # boolean search @@ -48,6 +58,10 @@ select * from t1 where MATCH a,b AGAINST ('"text i"' IN BOOLEAN MODE); select * from t1 where MATCH a AGAINST ("search" IN BOOLEAN MODE); select * from t1 where MATCH b AGAINST ("sear*" IN BOOLEAN MODE); +# UNION of fulltext's + +select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes"); + #update/delete with fulltext index delete from t1 where a like "MySQL%"; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 55f10ab930b..80e329a7f03 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1676,26 +1676,13 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC) { Item *item; - /* - I'm (Sergei) too lazy to implement proper recursive descent here, - and anyway, nobody will use such a stupid queries - that will require it :-) - May be later... - */ while ((item=li++)) - { - if (item->type() == Item::FUNC_ITEM && - ((Item_func *)item)->functype() == Item_func::FT_FUNC) - { - cond_func=(Item_func_match *)item; - break; - } - } + add_ft_keys(keyuse_array,stat,item,usable_tables); } } - if ((!cond_func || cond_func->key == NO_SUCH_KEY) || - (!(usable_tables & cond_func->table->map))) + if (!cond_func || cond_func->key == NO_SUCH_KEY || + !(usable_tables & cond_func->table->map)) return; KEYUSE keyuse; @@ -1707,7 +1694,6 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array, VOID(insert_dynamic(keyuse_array,(gptr) &keyuse)); } - static int sort_keyuse(KEYUSE *a,KEYUSE *b) { From 74ac300642d83a50e328a679954e5af5df8cdd3f Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 7 Jul 2003 19:35:11 +0200 Subject: [PATCH 139/237] typos fixed --- sql/mysqld.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c45b3184f16..b23dcb2e439 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3598,17 +3598,17 @@ relay logs", {"skip-stack-trace", OPT_SKIP_STACK_TRACE, "Don't print a stack trace on failure", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Depricated option. Use --skip-symbolic-links instead", + {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. Deprecated option. Use --skip-symbolic-links instead", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-thread-priority", OPT_SKIP_PRIOR, "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE, + {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE, "The location and name of the file that remembers where the SQL replication \ thread is in the relay logs", (gptr*) &relay_log_info_file, (gptr*) &relay_log_info_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR, + {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR, "The location where the slave should put its temporary files when \ replicating a LOAD DATA INFILE command", (gptr*) &slave_load_tmpdir, (gptr*) &slave_load_tmpdir, 0, GET_STR_ALLOC, @@ -3630,7 +3630,7 @@ replicating a LOAD DATA INFILE command", #ifdef HAVE_OPENSSL #include "sslopt-longopts.h" #endif - {"temp-pool", OPT_TEMP_POOL, + {"temp-pool", OPT_TEMP_POOL, "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.", (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, @@ -3642,10 +3642,10 @@ replicating a LOAD DATA INFILE command", {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running", (gptr*) &opt_external_locking, (gptr*) &opt_external_locking, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"use-symbolic-links", 's', "Enable symbolic link support. Depricated option; Use --symbolic-links instead", + {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; Use --symbolic-links instead", (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, IF_PURIFY(0,1), 0, 0, 0, 0, 0}, - {"--symbolic-links", 's', "Enable symbolic link support", + {"symbolic-links", 's', "Enable symbolic link support", (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, IF_PURIFY(0,1), 0, 0, 0, 0, 0}, {"user", 'u', "Run mysqld daemon as user", 0, 0, 0, GET_STR, REQUIRED_ARG, From 99d224420d5d63045c577279c18b031d18666ace Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 8 Jul 2003 14:16:27 +0300 Subject: [PATCH 140/237] trx0trx.c: A cosmetic change: set trx id to zero at creation so that SHOW INNODB STATUS does not print a random value for the id of a transaction object for which the transaction has never been started yet (for example, running SHOW INNODB STATUS as the first command from a mysql prompt printed a random id for the trx object associated with the session itself running the SHOW INNODB STATUS command) --- innobase/trx/trx0trx.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index 0dead50264b..e8d6c093680 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -86,6 +86,10 @@ trx_create( trx->start_time = time(NULL); trx->isolation_level = TRX_ISO_REPEATABLE_READ; + + trx->id = ut_dulint_zero; + trx->no = ut_dulint_max; + trx->check_foreigns = TRUE; trx->check_unique_secondary = TRUE; From 46b0e778b8ab8e7d303545c8fff58be3db74859c Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Tue, 8 Jul 2003 15:50:57 +0200 Subject: [PATCH 141/237] Fix for BUG#797 "If query ignored on slave (replicate-ignore-table) the slave still checks if the returned error (0) is the same as the one on the master, whereas it shouldn't test this. Plus a new test for BUG#797. --- include/mysqld_error.h | 3 ++- mysql-test/r/rpl_error_ignored_table.result | 15 +++++++++++++ .../t/rpl_error_ignored_table-slave.opt | 1 + mysql-test/t/rpl_error_ignored_table.test | 22 +++++++++++++++++++ sql/log.cc | 11 +++------- sql/log_event.cc | 3 ++- sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + sql/sql_parse.cc | 18 +++++++++------ 29 files changed, 78 insertions(+), 17 deletions(-) create mode 100644 mysql-test/r/rpl_error_ignored_table.result create mode 100644 mysql-test/t/rpl_error_ignored_table-slave.opt create mode 100644 mysql-test/t/rpl_error_ignored_table.test diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 0898b3d576f..9d3197c0bd4 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -253,4 +253,5 @@ #define ER_CANT_USE_OPTION_HERE 1234 #define ER_NOT_SUPPORTED_YET 1235 #define ER_MASTER_FATAL_ERROR_READING_BINLOG 1236 -#define ER_ERROR_MESSAGES 237 +#define ER_SLAVE_IGNORED_TABLE 1237 /* only the slave SQL thread can be sent this */ +#define ER_ERROR_MESSAGES 238 diff --git a/mysql-test/r/rpl_error_ignored_table.result b/mysql-test/r/rpl_error_ignored_table.result new file mode 100644 index 00000000000..826e97a8004 --- /dev/null +++ b/mysql-test/r/rpl_error_ignored_table.result @@ -0,0 +1,15 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +create table t1 (a int primary key); +insert into t1 values (1),(1); +Duplicate entry '1' for key 1 +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9306 1 master-bin.001 213 slave-relay-bin.002 254 master-bin.001 Yes Yes 0 0 213 254 +show tables like 't1'; +Tables_in_test (t1) +drop table t1; diff --git a/mysql-test/t/rpl_error_ignored_table-slave.opt b/mysql-test/t/rpl_error_ignored_table-slave.opt new file mode 100644 index 00000000000..544ecb2959b --- /dev/null +++ b/mysql-test/t/rpl_error_ignored_table-slave.opt @@ -0,0 +1 @@ +--replicate-ignore-table=test.t1 \ No newline at end of file diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test new file mode 100644 index 00000000000..caa289a184d --- /dev/null +++ b/mysql-test/t/rpl_error_ignored_table.test @@ -0,0 +1,22 @@ +# Test for +# Bug #797: If a query is ignored on slave (replicate-ignore-table) the slave +# still checks that it has the same error as on the master. + +source include/master-slave.inc; +connection master; +create table t1 (a int primary key); +# generate an error that goes to the binlog +--error 1062; +insert into t1 values (1),(1); +save_master_pos; +connection slave; +# as the t1 table is ignored on the slave, the slave should be able to sync +sync_with_master; +show slave status; +# check that the table has been ignored, because otherwise the test is nonsense +show tables like 't1'; +connection master; +drop table t1; +save_master_pos; +connection slave; +sync_with_master; diff --git a/sql/log.cc b/sql/log.cc index ef7cdd0dbd5..7bcdc12ddf1 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -875,14 +875,9 @@ void MYSQL_LOG::new_file(bool need_lock) save_log_type=log_type; name=0; // Don't free name close(); -/* - if (save_log_type == LOG_BIN) - { - printf("after close, before open; I wait for 20 seconds\n"); - sleep(20); - printf("sleep finished, opening\n"); - } -*/ + + // TODO: at this place is_open() will see the log closed, which is BUG#791. + open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type, no_auto_events, max_size); my_free(old_name,MYF(0)); diff --git a/sql/log_event.cc b/sql/log_event.cc index 5f3d4263642..a6d2abbf894 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -69,7 +69,8 @@ static void pretty_print_str(FILE* file, char* str, int len) inline int ignored_error_code(int err_code) { - return use_slave_mask && bitmap_is_set(&slave_error_mask, err_code); + return ((err_code == ER_SLAVE_IGNORED_TABLE) || + (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code))); } diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index f5e879679cc..72a593cf5f7 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -247,3 +247,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 13c061d50a1..f59abfeb6da 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -241,3 +241,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 45dbd663fec..974b4601ac8 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -249,3 +249,4 @@ "Foutieve toepassing/plaatsing van '%s'", "Deze versie van MySQL ondersteunt nog geen '%s'", "Kreeg fatale fout %d: '%-.128s' van master tijdens lezen van data uit binaire log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index b7910bd07b3..3d7ca3b28df 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index c1b98d12b3a..38b45c1443b 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -243,3 +243,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 242343769e6..df2be2803b4 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 10ec359abe8..cdeab579eca 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -241,3 +241,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 11534d9e11b..e3778aaac10 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index f8c5dbcc836..85ea5c2e742 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -240,3 +240,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index a82b0cdf18f..3be8058661a 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -238,3 +238,4 @@ "Uso/posizione di '%s' sbagliato", "Questa versione di MySQL non supporta ancora '%s'", "Errore fatale %d: '%-.128s' dal master leggendo i dati dal log binario", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 1b04ee5c2e4..f99d262a689 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -240,3 +240,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index c57723f81e6..2a7e03b026d 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index e331854ff68..e6ec84e98a0 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -240,3 +240,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 817eec3058d..fe379261151 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -240,3 +240,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index e5bede3b48c..a300dc1e2ab 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -242,3 +242,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index ea4f85f6b03..f9f37bfd924 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -238,3 +238,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 7fc0c182f6a..bf1306cd332 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -242,3 +242,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index fc090205041..03964efb26b 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -240,3 +240,4 @@ "îÅ×ÅÒÎÏÅ ÉÓÐÏÌØÚÏ×ÁÎÉÅ ÉÌÉ × ÎÅ×ÅÒÎÏÍ ÍÅÓÔÅ ÕËÁÚÁÎ '%s'", "üÔÁ ×ÅÒÓÉÑ MySQL ÐÏËÁ ÅÝÅ ÎÅ ÐÏÄÄÅÒÖÉ×ÁÅÔ '%s'", "ðÏÌÕÞÅÎÁ ÎÅÉÓÐÒÁ×ÉÍÁÑ ÏÛÉÂËÁ %d: '%-.128s' ÏÔ ÇÏÌÏ×ÎÏÇÏ ÓÅÒ×ÅÒÁ × ÐÒÏÃÅÓÓÅ ×ÙÂÏÒËÉ ÄÁÎÎÙÈ ÉÚ Ä×ÏÉÞÎÏÇÏ ÖÕÒÎÁÌÁ", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 89a000db554..b9970465871 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -246,3 +246,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index c8e33325786..78b7e5ac907 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -239,3 +239,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 7ef663839c9..32eec834ed1 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -238,3 +238,4 @@ "Fel använding/placering av '%s'", "Denna version av MySQL kan ännu inte utföra '%s'", "Fick fatalt fel %d: '%-.128s' från master vid läsning av binärloggen" +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index a0a4a274d4b..c0931ab9f02 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -243,3 +243,4 @@ "Wrong usage/placement of '%s'", "This version of MySQL doesn't yet support '%s'", "Got fatal error %d: '%-.128s' from master when reading data from binary log", +"Slave SQL thread ignored the query because of replicate-*-table rules" diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4db802ffbcc..7e2aefc493d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1324,7 +1324,11 @@ mysql_execute_command(void) given and the table list says the query should not be replicated */ if (table_rules_on && tables && !tables_ok(thd,tables)) + { + /* we warn the slave SQL thread */ + my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); DBUG_VOID_RETURN; + } #ifndef TO_BE_DELETED /* This is a workaround to deal with the shortcoming in 3.23.44-3.23.46 @@ -1339,13 +1343,7 @@ mysql_execute_command(void) #endif } - /* - Skip if we are in the slave thread, some table rules have been given - and the table list says the query should not be replicated - */ - if ((lex->select_lex.next && create_total_list(thd,lex,&tables)) || - (table_rules_on && tables && thd->slave_thread && - !tables_ok(thd,tables))) + if (lex->select_lex.next && create_total_list(thd,lex,&tables)) DBUG_VOID_RETURN; /* @@ -2330,7 +2328,10 @@ mysql_execute_command(void) if (thd->slave_thread && (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) + { + my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); break; + } if (check_access(thd,CREATE_ACL,lex->name,0,1)) break; @@ -2354,7 +2355,10 @@ mysql_execute_command(void) if (thd->slave_thread && (!db_ok(lex->name, replicate_do_db, replicate_ignore_db) || !db_ok_with_wild_table(lex->name))) + { + my_error(ER_SLAVE_IGNORED_TABLE, MYF(0)); break; + } if (check_access(thd,DROP_ACL,lex->name,0,1)) break; if (thd->locked_tables || thd->active_transaction()) From dbf893fbd4b39ab0ace49996616619a2297c52a4 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 8 Jul 2003 17:27:22 +0200 Subject: [PATCH 142/237] added missing ~/.my.cnf support to mysqlhotcopy (bug #808) --- scripts/mysqlhotcopy.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index fa35a1c6555..7385be65092 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -81,6 +81,11 @@ sub usage { die @_, $OPTIONS; } +# reading ~/.my.cnf +my @defops = `@bindir@/my_print_defaults client mysqlhotcopy`; +chop @defops; +splice @ARGV, 0, 0, @defops; + my %opt = ( user => scalar getpwuid($>), noindices => 0, From a5a3eb94393e11aef81d9bec76b3d10ba8fa343c Mon Sep 17 00:00:00 2001 From: "paul@teton.kitebird.com" <> Date: Tue, 8 Jul 2003 11:25:46 -0500 Subject: [PATCH 143/237] mysqlhotcopy.sh: Undo serg's patch that used my_print_defaults, and instead simply do not define $opt{user}. This allows the script to use option files properly. --- scripts/mysqlhotcopy.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index 7385be65092..fc89a967e16 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -81,13 +81,11 @@ sub usage { die @_, $OPTIONS; } -# reading ~/.my.cnf -my @defops = `@bindir@/my_print_defaults client mysqlhotcopy`; -chop @defops; -splice @ARGV, 0, 0, @defops; +# Do not initialize user or password options; that way, any user/password +# options specified in option files will be used. If no values are specified +# all, the defaults will be used (login name, no password). my %opt = ( - user => scalar getpwuid($>), noindices => 0, allowold => 0, # for safety keepold => 0, @@ -170,6 +168,9 @@ $dsn = ";host=" . (defined($opt{host}) ? $opt{host} : "localhost"); $dsn .= ";port=$opt{port}" if $opt{port}; $dsn .= ";mysql_socket=$opt{socket}" if $opt{socket}; +# use mysql_read_default_group=mysqlhotcopy so that [client] and +# [mysqlhotcopy] groups will be read from standard options files. + my $dbh = DBI->connect("dbi:mysql:$dsn;mysql_read_default_group=mysqlhotcopy", $opt{user}, $opt{password}, { From cc82126f5fef81af44c434498cf0577ce5d486fe Mon Sep 17 00:00:00 2001 From: "paul@teton.kitebird.com" <> Date: Tue, 8 Jul 2003 11:26:46 -0500 Subject: [PATCH 144/237] From f8a767b5d58f260493df6b5e0b01e123180d3783 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 8 Jul 2003 20:51:45 +0300 Subject: [PATCH 145/237] ha_innodb.cc: Prevent the user from creating InnoDB tables with > 1000 columns --- sql/ha_innodb.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 9857628ccc8..09119a4eb54 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3396,6 +3396,13 @@ ha_innobase::create( DBUG_ASSERT(thd != NULL); + if (form->fields > 1000) { + /* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020, + but we play safe here */ + + return(HA_ERR_TO_BIG_ROW); + } + /* Get the transaction associated with the current thd, or create one if not yet created */ From b2cbd83913d05369c17caa1248bf03f6d08abaf1 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Tue, 8 Jul 2003 23:58:04 +0300 Subject: [PATCH 146/237] Fixed bug in ALTER TABLE ... DISABLE/ENABLE KEYS Removed double my_thread_end() which caused fatal error on windows if mysqld died on startup --- myisam/mi_extra.c | 4 ++ mysql-test/r/alter_table.result | 69 +++++++++++++++++++++++++++++++++ mysql-test/t/alter_table.test | 62 +++++++++++++++++++++++++++++ sql/ha_myisam.cc | 7 +++- sql/mysqld.cc | 1 - sql/sql_table.cc | 14 ++++--- sql/table.cc | 3 ++ sql/table.h | 2 +- 8 files changed, 152 insertions(+), 10 deletions(-) diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c index 75057dd4e6a..ef82a6ef61f 100644 --- a/myisam/mi_extra.c +++ b/myisam/mi_extra.c @@ -273,6 +273,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) } break; case HA_EXTRA_FORCE_REOPEN: + pthread_mutex_lock(&THR_LOCK_myisam); + share->last_version= 0L; /* Impossible version */ + pthread_mutex_unlock(&THR_LOCK_myisam); + break; case HA_EXTRA_PREPARE_FOR_DELETE: pthread_mutex_lock(&THR_LOCK_myisam); share->last_version= 0L; /* Impossible version */ diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index e2d9cc30ad9..7ade3313abe 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -281,3 +281,72 @@ ALTER TABLE t1 DISABLE KEYS; INSERT DELAYED INTO t1 VALUES(1),(2),(3); ALTER TABLE t1 ENABLE KEYS; drop table t1; +CREATE TABLE t1 ( +Host varchar(16) binary NOT NULL default '', +User varchar(16) binary NOT NULL default '', +PRIMARY KEY (Host,User) +) TYPE=MyISAM; +ALTER TABLE t1 DISABLE KEYS; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''),('games','monty'); +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 3 NULL NULL BTREE +ALTER TABLE t1 ENABLE KEYS; +UNLOCK TABLES; +CHECK TABLES t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1 ( +Host varchar(16) binary NOT NULL default '', +User varchar(16) binary NOT NULL default '', +PRIMARY KEY (Host,User), +KEY (Host) +) TYPE=MyISAM; +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 0 NULL NULL BTREE +t1 1 Host 1 Host A NULL NULL NULL BTREE disabled +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''); +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 2 NULL NULL BTREE +t1 1 Host 1 Host A NULL NULL NULL BTREE disabled +ALTER TABLE t1 ENABLE KEYS; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 2 NULL NULL BTREE +t1 1 Host 1 Host A 1 NULL NULL BTREE +UNLOCK TABLES; +CHECK TABLES t1; +Table Op Msg_type Msg_text +test.t1 check status OK +LOCK TABLES t1 WRITE; +ALTER TABLE t1 RENAME t2; +UNLOCK TABLES; +select * from t2; +Host User +localhost +localhost root +DROP TABLE t2; +CREATE TABLE t1 ( +Host varchar(16) binary NOT NULL default '', +User varchar(16) binary NOT NULL default '', +PRIMARY KEY (Host,User), +KEY (Host) +) TYPE=MyISAM; +LOCK TABLES t1 WRITE; +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t1 0 PRIMARY 1 Host A NULL NULL NULL BTREE +t1 0 PRIMARY 2 User A 0 NULL NULL BTREE +t1 1 Host 1 Host A NULL NULL NULL BTREE disabled +DROP TABLE t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index a3ab62afc69..d438f2d5825 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -142,3 +142,65 @@ ALTER TABLE t1 DISABLE KEYS; INSERT DELAYED INTO t1 VALUES(1),(2),(3); ALTER TABLE t1 ENABLE KEYS; drop table t1; + +# +# Test ALTER TABLE ENABLE/DISABLE keys when things are locked +# + +CREATE TABLE t1 ( + Host varchar(16) binary NOT NULL default '', + User varchar(16) binary NOT NULL default '', + PRIMARY KEY (Host,User) +) TYPE=MyISAM; + +ALTER TABLE t1 DISABLE KEYS; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''),('games','monty'); +SHOW INDEX FROM t1; +ALTER TABLE t1 ENABLE KEYS; +UNLOCK TABLES; +CHECK TABLES t1; +DROP TABLE t1; + +# +# Test with two keys +# + +CREATE TABLE t1 ( + Host varchar(16) binary NOT NULL default '', + User varchar(16) binary NOT NULL default '', + PRIMARY KEY (Host,User), + KEY (Host) +) TYPE=MyISAM; + +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +LOCK TABLES t1 WRITE; +INSERT INTO t1 VALUES ('localhost','root'),('localhost',''); +SHOW INDEX FROM t1; +ALTER TABLE t1 ENABLE KEYS; +SHOW INDEX FROM t1; +UNLOCK TABLES; +CHECK TABLES t1; + +# Test RENAME with LOCK TABLES +LOCK TABLES t1 WRITE; +ALTER TABLE t1 RENAME t2; +UNLOCK TABLES; +select * from t2; +DROP TABLE t2; + +# +# Test disable keys with locking +# +CREATE TABLE t1 ( + Host varchar(16) binary NOT NULL default '', + User varchar(16) binary NOT NULL default '', + PRIMARY KEY (Host,User), + KEY (Host) +) TYPE=MyISAM; + +LOCK TABLES t1 WRITE; +ALTER TABLE t1 DISABLE KEYS; +SHOW INDEX FROM t1; +DROP TABLE t1; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 202cd90fd88..595123f7ac1 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -715,6 +715,7 @@ void ha_myisam::deactivate_non_unique_index(ha_rows rows) } } enable_activate_all_index=1; + info(HA_STATUS_CONST); // Read new key info } else enable_activate_all_index=0; @@ -743,6 +744,7 @@ bool ha_myisam::activate_all_index(THD *thd) param.sort_buffer_length= thd->variables.myisam_sort_buff_size; param.tmpdir=mysql_tmpdir; error=repair(thd,param,0) != HA_ADMIN_OK; + info(HA_STATUS_CONST); thd->proc_info=save_proc_info; } else @@ -926,8 +928,9 @@ void ha_myisam::info(uint flag) ref_length=info.reflength; table->db_options_in_use = info.options; block_size=myisam_block_size; - table->keys_in_use&= info.key_map; - table->keys_for_keyread&= info.key_map; + table->keys_in_use= (set_bits(key_map, table->keys) & + (key_map) info.key_map); + table->keys_for_keyread= table->keys_in_use & ~table->read_only_keys; table->db_record_offset=info.record_offset; if (table->key_parts) memcpy((char*) table->key_info[0].rec_per_key, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4f6f55bce0b..95bf94c8e8b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -871,7 +871,6 @@ extern "C" void unireg_abort(int exit_code) sql_print_error("Aborting\n"); clean_up(1); /* purecov: inspected */ DBUG_PRINT("quit",("done with cleanup in unireg_abort")); - my_thread_end(); clean_up_mutexes(); my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(exit_code); /* purecov: inspected */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5a53ba30631..cf430aec35d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -918,7 +918,8 @@ mysql_rename_table(enum db_type base, wait_while_table_is_used() thd Thread handler table Table to remove from cache - + function HA_EXTRA_PREPARE_FOR_DELETE if table is to be deleted + HA_EXTRA_FORCE_REOPEN if table is not be used NOTES When returning, the table will be unusable for other threads until the table is closed. @@ -928,13 +929,14 @@ mysql_rename_table(enum db_type base, Win32 clients must also have a WRITE LOCK on the table ! */ -static void wait_while_table_is_used(THD *thd,TABLE *table) +static void wait_while_table_is_used(THD *thd,TABLE *table, + enum ha_extra_function function) { DBUG_PRINT("enter",("table: %s", table->real_name)); DBUG_ENTER("wait_while_table_is_used"); safe_mutex_assert_owner(&LOCK_open); - VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files + VOID(table->file->extra(function)); /* Mark all tables that are in use as 'old' */ mysql_lock_abort(thd, table); // end threads waiting on lock @@ -970,7 +972,7 @@ static bool close_cached_table(THD *thd, TABLE *table) { DBUG_ENTER("close_cached_table"); - wait_while_table_is_used(thd,table); + wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DELETE); /* Close lock if this is not got with LOCK TABLES */ if (thd->lock) { @@ -1529,14 +1531,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, break; case ENABLE: VOID(pthread_mutex_lock(&LOCK_open)); - wait_while_table_is_used(thd, table); + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); VOID(pthread_mutex_unlock(&LOCK_open)); error= table->file->activate_all_index(thd); /* COND_refresh will be signaled in close_thread_tables() */ break; case DISABLE: VOID(pthread_mutex_lock(&LOCK_open)); - wait_while_table_is_used(thd, table); + wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); VOID(pthread_mutex_unlock(&LOCK_open)); table->file->deactivate_non_unique_index(HA_POS_ERROR); /* COND_refresh will be signaled in close_thread_tables() */ diff --git a/sql/table.cc b/sql/table.cc index a26ab89bd97..e938757cf6c 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -422,7 +422,10 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, /* This has to be done after the above fulltext correction */ index_flags=outparam->file->index_flags(key); if (!(index_flags & HA_KEY_READ_ONLY)) + { + outparam->read_only_keys|= ((key_map) 1 << key); outparam->keys_for_keyread&= ~((key_map) 1 << key); + } if (primary_key >= MAX_KEY && (keyinfo->flags & HA_NOSAME)) { diff --git a/sql/table.h b/sql/table.h index b6935ea6a32..57be97ffbda 100644 --- a/sql/table.h +++ b/sql/table.h @@ -62,7 +62,7 @@ struct st_table { uint uniques; uint null_fields; /* number of null fields */ uint blob_fields; /* number of blob fields */ - key_map keys_in_use, keys_for_keyread; + key_map keys_in_use, keys_for_keyread, read_only_keys; key_map quick_keys, used_keys, keys_in_use_for_query; KEY *key_info; /* data of keys in database */ TYPELIB keynames; /* Pointers to keynames */ From 7326dcbf23c0c5a2c68d57809e2934b9986d9d6b Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Tue, 8 Jul 2003 23:29:55 +0200 Subject: [PATCH 147/237] - Fixed mysqlhotcopy to actually abort if copying the tables failed. (BUG#812) --- scripts/mysqlhotcopy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index fc89a967e16..98a5c5b9f85 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -660,9 +660,9 @@ sub safe_system print "Executing '@cmd'\n" if $opt{debug}; my $cp_status = system "@cmd > /dev/null"; if ($cp_status != 0) { - warn "Burp ('scuse me). Trying backtick execution...\n" if $opt{debug}; #' + warn "Executing command failed ($cp_status). Trying backtick execution...\n"; ## try something else - `@cmd` && die "Error: @cmd failed ($cp_status) while copying files.\n"; + `@cmd` || die "Error: @cmd failed ($?) while copying files.\n"; } } From d495656ac58a2fca1cc5b1ffd3e36985cbcb0baa Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Wed, 9 Jul 2003 00:55:07 +0300 Subject: [PATCH 148/237] Cleanups --- mysql-test/t/distinct.test | 7 +++-- sql/log.cc | 10 +++---- sql/slave.cc | 53 ++++++++++++++++++++------------------ sql/sql_delete.cc | 15 ++++++----- sql/sql_parse.cc | 2 +- 5 files changed, 48 insertions(+), 39 deletions(-) diff --git a/mysql-test/t/distinct.test b/mysql-test/t/distinct.test index 1cc692bd886..79770a17baa 100644 --- a/mysql-test/t/distinct.test +++ b/mysql-test/t/distinct.test @@ -273,11 +273,14 @@ CREATE TABLE t2 (a int primary key, b int, c int); INSERT t2 VALUES (3,4,5); SELECT DISTINCT t1.a, t2.b FROM t1, t2 WHERE t1.a=1 ORDER BY t2.c; DROP TABLE IF EXISTS t1,t2; + +# +# Test of LEFT() with distinct +# + CREATE table t1 ( `id` int(11) NOT NULL auto_increment, `name` varchar(50) NOT NULL default '', PRIMARY KEY (`id`)) TYPE=MyISAM AUTO_INCREMENT=3 ; INSERT INTO t1 VALUES (1, 'aaaaa'); INSERT INTO t1 VALUES (3, 'aaaaa'); INSERT INTO t1 VALUES (2, 'eeeeeee'); select distinct left(name,1) as name from t1; drop table t1; - - diff --git a/sql/log.cc b/sql/log.cc index 7bcdc12ddf1..c24c2f2e39b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -141,7 +141,7 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, io_cache_type = io_cache_type_arg; no_auto_events = no_auto_events_arg; max_size=max_size_arg; - DBUG_PRINT("info",("log_type=%d max_size=%lu", log_type, max_size)); + DBUG_PRINT("info",("log_type: %d max_size: %lu", log_type, max_size)); if (!inited) { inited= 1; @@ -909,7 +909,7 @@ bool MYSQL_LOG::append(Log_event* ev) goto err; } bytes_written += ev->get_event_len(); - DBUG_PRINT("info",("max_size=%lu",max_size)); + DBUG_PRINT("info",("max_size: %lu",max_size)); if ((uint) my_b_append_tell(&log_file) > max_size) { pthread_mutex_lock(&LOCK_index); @@ -943,7 +943,7 @@ bool MYSQL_LOG::appendv(const char* buf, uint len,...) } bytes_written += len; } while ((buf=va_arg(args,const char*)) && (len=va_arg(args,uint))); - DBUG_PRINT("info",("max_size=%lu",max_size)); + DBUG_PRINT("info",("max_size: %lu",max_size)); if ((uint) my_b_append_tell(&log_file) > max_size) { pthread_mutex_lock(&LOCK_index); @@ -1206,7 +1206,7 @@ bool MYSQL_LOG::write(Log_event* event_info) } } /* We wrote to the real log, check automatic rotation; */ - DBUG_PRINT("info",("max_size=%lu",max_size)); + DBUG_PRINT("info",("max_size: %lu",max_size)); should_rotate= (my_b_tell(file) >= (my_off_t) max_size); } error=0; @@ -1337,7 +1337,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache) log_file.pos_in_file))) goto err; signal_update(); - DBUG_PRINT("info",("max_size=%lu",max_size)); + DBUG_PRINT("info",("max_size: %lu",max_size)); if (my_b_tell(&log_file) >= (my_off_t) max_size) { pthread_mutex_lock(&LOCK_index); diff --git a/sql/slave.cc b/sql/slave.cc index f004ed538b0..e0ca4f1ad7a 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1205,10 +1205,10 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) /* The relay log will now be opened, as a SEQ_READ_APPEND IO_CACHE. It is - notable that the last kilobytes of it (8 kB for example) may live in memory, - not on disk (depending on what the thread using it does). While this is - efficient, it has a side-effect one must know: - the size of the relay log on disk (displayed by 'ls -l' on Unix) can be a + notable that the last kilobytes of it (8 kB for example) may live in + memory, not on disk (depending on what the thread using it does). While + this is efficient, it has a side-effect one must know: + The size of the relay log on disk (displayed by 'ls -l' on Unix) can be a few kilobytes less than one would expect by doing SHOW SLAVE STATUS; this happens when only the IO thread is started (not the SQL thread). The "missing" kilobytes are in memory, are preserved during 'STOP SLAVE; START @@ -1221,30 +1221,31 @@ int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname) See how 4 is less than 7811 and 8192 is less than 9744. - WARNING: this is risky because the slave can stay like this for a long time; - then if it has a power failure, master.info says the I/O thread has read - until 9744 while the relay-log contains only until 8192 (the in-memory part - from 8192 to 9744 has been lost), so the SQL slave thread will miss some - events, silently breaking replication. + WARNING: this is risky because the slave can stay like this for a long + time; then if it has a power failure, master.info says the I/O thread has + read until 9744 while the relay-log contains only until 8192 (the + in-memory part from 8192 to 9744 has been lost), so the SQL slave thread + will miss some events, silently breaking replication. Ideally we would like to flush master.info only when we know that the relay log has no in-memory tail. Note that the above problem may arise only when only the IO thread is started, which is unlikely. */ + /* + For the maximum log size, we choose max_relay_log_size if it is + non-zero, max_binlog_size otherwise. If later the user does SET + GLOBAL on one of these variables, fix_max_binlog_size and + fix_max_relay_log_size will reconsider the choice (for example + if the user changes max_relay_log_size to zero, we have to + switch to using max_binlog_size for the relay log) and update + rli->relay_log.max_size (and mysql_bin_log.max_size). + */ + if (open_log(&rli->relay_log, glob_hostname, opt_relay_logname, "-relay-bin", opt_relaylog_index_name, LOG_BIN, 1 /* read_append cache */, 1 /* no auto events */, - /* - For the maximum size, we choose max_relay_log_size if it is - non-zero, max_binlog_size otherwise. If later the user does SET - GLOBAL on one of these variables, fix_max_binlog_size and - fix_max_relay_log_size will reconsider the choice (for example - if the user changes max_relay_log_size to zero, we have to - switch to using max_binlog_size for the relay log) and update - rli->relay_log.max_size (and mysql_bin_log.max_size). - */ max_relay_log_size ? max_relay_log_size : max_binlog_size)) { sql_print_error("Failed in open_log() called from init_relay_log_info()"); @@ -3445,23 +3446,25 @@ void rotate_relay_log(MASTER_INFO* mi) /* If this server is not a slave (or RESET SLAVE has just been run) */ if (!rli->inited) { - DBUG_PRINT("info", ("rli->inited=0")); + DBUG_PRINT("info", ("rli->inited == 0")); DBUG_VOID_RETURN; } lock_slave_threads(mi); pthread_mutex_lock(&rli->data_lock); + /* If the relay log is closed, new_file() will do nothing. */ rli->relay_log.new_file(1); + /* We harvest now, because otherwise BIN_LOG_HEADER_SIZE will not immediately be counted, so imagine a succession of FLUSH LOGS and assume the slave threads are started: - relay_log_space decreases by the size of the deleted relay log, but does not - increase, so flush-after-flush we may become negative, which is wrong. - Even if this will be corrected as soon as a query is replicated on the slave - (because the I/O thread will then call harvest_bytes_written() which will - harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange output - in SHOW SLAVE STATUS meanwhile. So we harvest now. + relay_log_space decreases by the size of the deleted relay log, but does + not increase, so flush-after-flush we may become negative, which is wrong. + Even if this will be corrected as soon as a query is replicated on the + slave (because the I/O thread will then call harvest_bytes_written() which + will harvest all these BIN_LOG_HEADER_SIZE we forgot), it may give strange + output in SHOW SLAVE STATUS meanwhile. So we harvest now. If the log is closed, then this will just harvest the last writes, probably 0 as they probably have been harvested. */ diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 96638617610..45acbaaa7ef 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -145,12 +145,15 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, else { table->file->print_error(error,MYF(0)); - error=1; /* In < 4.0.14 we set the error number to 0 here, but that - was not sensible, because then MySQL would not roll back the - failed DELETE, and also wrote it to the binlog. For MyISAM - tables a DELETE probably never should fail (?), but for - InnoDB it can fail in a FOREIGN KEY error or an - out-of-tablespace error. (Comment by Heikki July 7, 2003) */ + /* + In < 4.0.14 we set the error number to 0 here, but that + was not sensible, because then MySQL would not roll back the + failed DELETE, and also wrote it to the binlog. For MyISAM + tables a DELETE probably never should fail (?), but for + InnoDB it can fail in a FOREIGN KEY error or an + out-of-tablespace error. + */ + error= 1; break; } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7e2aefc493d..70c0f772d7d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2178,7 +2178,7 @@ mysql_execute_command(void) } if (check_access(thd,SELECT_ACL,db,&thd->col_access)) goto error; /* purecov: inspected */ - if (!thd->col_access && grant_option && check_grant_db(thd,db)) + if (!thd->col_access && check_grant_db(thd,db)) { net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, thd->priv_user, From f4ec8a73da57547771b77317ad5592121e7a63e0 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 9 Jul 2003 15:51:31 +0200 Subject: [PATCH 149/237] - enhanced the RPM spec file (use more RPM macros, cleanups, allow to override CC/CXX when using a special compiler) - the RPM should now build on AMD64 and IA64, too --- support-files/MySQL-shared-compat.spec.sh | 2 +- support-files/mysql.spec.sh | 219 ++++++++++++---------- 2 files changed, 120 insertions(+), 101 deletions(-) diff --git a/support-files/MySQL-shared-compat.spec.sh b/support-files/MySQL-shared-compat.spec.sh index f569dc20f42..06dfec1f6f9 100644 --- a/support-files/MySQL-shared-compat.spec.sh +++ b/support-files/MySQL-shared-compat.spec.sh @@ -69,4 +69,4 @@ rpm2cpio %{SOURCE1} | cpio -iv --make-directories %files %defattr(-, root, root) -/usr/lib/libmysqlclient* +%{_libdir}/libmysqlclient* diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 6cc33866efd..15127edeef4 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -1,7 +1,7 @@ %define mysql_version @VERSION@ -%define shared_lib_version @SHARED_LIB_VERSION@ %define release 0 %define mysqld_user mysql +%define server_suffix -standard %define see_base For a description of MySQL see the base MySQL RPM or http://www.mysql.com @@ -14,7 +14,6 @@ Version: @MYSQL_NO_DASH_VERSION@ Release: %{release} Copyright: GPL Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_version}.tar.gz -Icon: mysql.gif URL: http://www.mysql.com/ Packager: Lenz Grimmer Vendor: MySQL AB @@ -194,6 +193,8 @@ BuildMySQL() { # The --enable-assembler simply does nothing on systems that does not # support assembler speedups. sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ + CC=\"${CC:-$MYSQL_BUILD_CC}\" \ + CXX=\"${CXX:-$MYSQL_BUILD_CXX}\" \ CFLAGS=\"${MYSQL_BUILD_CFLAGS:-$RPM_OPT_FLAGS}\" \ CXXFLAGS=\"${MYSQL_BUILD_CXXFLAGS:-$RPM_OPT_FLAGS \ -felide-constructors -fno-exceptions -fno-rtti \ @@ -206,13 +207,14 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --with-unix-socket-path=/var/lib/mysql/mysql.sock \ --prefix=/ \ --with-extra-charsets=complex \ - --exec-prefix=/usr \ - --libexecdir=/usr/sbin \ - --sysconfdir=/etc \ - --datadir=/usr/share \ + --exec-prefix=%{_exec_prefix} \ + --libexecdir=%{_sbindir} \ + --libdir=%{_libdir} \ + --sysconfdir=%{_sysconfdir} \ + --datadir=%{_datadir} \ --localstatedir=/var/lib/mysql \ --infodir=%{_infodir} \ - --includedir=/usr/include \ + --includedir=%{_includedir} \ --mandir=%{_mandir} \ --with-embedded-server \ --enable-thread-safe-client \ @@ -284,13 +286,15 @@ make distclean mv Docs/manual.ps.save Docs/manual.ps # RPM:s destroys Makefile.in files, so we generate them here -automake +# aclocal; autoheader; aclocal; automake; autoconf +# (cd innobase && aclocal && autoheader && aclocal && automake && autoconf) # Now build the statically linked 4.0 binary (which includes InnoDB) BuildMySQL "--disable-shared \ --with-mysqld-ldflags='-all-static' \ --with-client-ldflags='-all-static' \ $USE_OTHER_LIBC_DIR \ + --with-server-suffix='%{server_suffix}' \ --without-berkeley-db \ --with-innodb \ --without-vio \ @@ -302,51 +306,54 @@ RBR=$RPM_BUILD_ROOT MBD=$RPM_BUILD_DIR/mysql-%{mysql_version} # Ensure that needed directories exists -install -d $RBR/etc/{logrotate.d,init.d} +install -d $RBR%{_sysconfdir}/{logrotate.d,init.d} install -d $RBR/var/lib/mysql/mysql -install -d $RBR/usr/share/{sql-bench,mysql-test} +install -d $RBR%{_datadir}/{sql-bench,mysql-test} +install -d $RBR%{_includedir} +install -d $RBR%{_libdir} install -d $RBR%{_mandir} -install -d $RBR/usr/{sbin,lib,include} +install -d $RBR%{_sbindir} + # Install all binaries stripped -make install-strip DESTDIR=$RBR benchdir_root=/usr/share/ +make install-strip DESTDIR=$RBR benchdir_root=%{_datadir} # Install shared libraries (Disable for architectures that don't support it) -(cd $RBR/usr/lib; tar xf $RBR/shared-libs.tar) +(cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar) # install saved mysqld-max -install -s -m755 $MBD/sql/mysqld-max $RBR/usr/sbin/mysqld-max +install -s -m755 $MBD/sql/mysqld-max $RBR%{_sbindir}/mysqld-max # install symbol files ( for stack trace resolution) -install -m644 $MBD/sql/mysqld-max.sym $RBR/usr/lib/mysql/mysqld-max.sym -install -m644 $MBD/sql/mysqld.sym $RBR/usr/lib/mysql/mysqld.sym +install -m644 $MBD/sql/mysqld-max.sym $RBR%{_libdir}/mysql/mysqld-max.sym +install -m644 $MBD/sql/mysqld.sym $RBR%{_libdir}/mysql/mysqld.sym # Install logrotate and autostart -install -m644 $MBD/support-files/mysql-log-rotate $RBR/etc/logrotate.d/mysql -install -m755 $MBD/support-files/mysql.server $RBR/etc/init.d/mysql +install -m644 $MBD/support-files/mysql-log-rotate $RBR%{_sysconfdir}/logrotate.d/mysql +install -m755 $MBD/support-files/mysql.server $RBR%{_sysconfdir}/init.d/mysql # Create a symlink "rcmysql", pointing to the init.script. SuSE users # will appreciate that, as all services usually offer this. -ln -s ../../etc/init.d/mysql $RPM_BUILD_ROOT/usr/sbin/rcmysql +ln -s %{_sysconfdir}/init.d/mysql $RPM_BUILD_ROOT%{_sbindir}/rcmysql # Create symbolic compatibility link safe_mysqld -> mysqld_safe # (safe_mysqld will be gone in MySQL 4.1) -ln -sf ./mysqld_safe $RBR/usr/bin/safe_mysqld +ln -sf ./mysqld_safe $RBR%{_bindir}/safe_mysqld # Touch the place where the my.cnf config file might be located # Just to make sure it's in the file list and marked as a config file -touch $RBR/etc/my.cnf +touch $RBR%{_sysconfdir}/my.cnf %pre server # Shut down a previously installed server first -if test -x /etc/init.d/mysql +if test -x %{_sysconfdir}/init.d/mysql then - /etc/init.d/mysql stop > /dev/null 2>&1 + %{_sysconfdir}/init.d/mysql stop > /dev/null 2>&1 echo "Giving mysqld a couple of seconds to exit nicely" sleep 5 -elif test -x /etc/rc.d/init.d/mysql +elif test -x %{_sysconfdir}/rc.d/init.d/mysql then - /etc/rc.d/init.d/mysql stop > /dev/null 2>&1 + %{_sysconfdir}/rc.d/init.d/mysql stop > /dev/null 2>&1 echo "Giving mysqld a couple of seconds to exit nicely" sleep 5 fi @@ -363,7 +370,7 @@ if test ! -d $mysql_datadir/test; then mkdir $mysql_datadir/test; fi # use insserv for older SuSE Linux versions if test -x /sbin/insserv then - /sbin/insserv /etc/init.d/mysql + /sbin/insserv %{_sysconfdir}/init.d/mysql # use chkconfig on Red Hat and newer SuSE releases elif test -x /sbin/chkconfig then @@ -389,7 +396,7 @@ chown -R mysql $mysql_datadir chmod -R og-rw $mysql_datadir/mysql # Restart in the same way that mysqld will be started normally. -/etc/init.d/mysql start +%{_sysconfdir}/init.d/mysql start # Allow safe_mysqld to start mysqld and print a message before we exit sleep 2 @@ -397,22 +404,22 @@ sleep 2 %post Max # Restart mysqld, to use the new binary. echo "Restarting mysqld." -/etc/init.d/mysql restart > /dev/null 2>&1 +%{_sysconfdir}/init.d/mysql restart > /dev/null 2>&1 %preun server if test $1 = 0 then # Stop MySQL before uninstalling it - if test -x /etc/init.d/mysql + if test -x %{_sysconfdir}/init.d/mysql then - /etc/init.d/mysql stop > /dev/null + %{_sysconfdir}/init.d/mysql stop > /dev/null fi # Remove autostart of mysql # for older SuSE Linux versions if test -x /sbin/insserv then - /sbin/insserv -r /etc/init.d/mysql + /sbin/insserv -r %{_sysconfdir}/init.d/mysql # use chkconfig on Red Hat and newer SuSE releases elif test -x /sbin/chkconfig then @@ -445,54 +452,54 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/perror.1* %doc %attr(644, root, man) %{_mandir}/man1/replace.1* -%ghost %config(noreplace,missingok) /etc/my.cnf +%ghost %config(noreplace,missingok) %{_sysconfdir}/my.cnf -%attr(755, root, root) /usr/bin/isamchk -%attr(755, root, root) /usr/bin/isamlog -%attr(755, root, root) /usr/bin/my_print_defaults -%attr(755, root, root) /usr/bin/myisamchk -%attr(755, root, root) /usr/bin/myisamlog -%attr(755, root, root) /usr/bin/myisampack -%attr(755, root, root) /usr/bin/mysql_convert_table_format -%attr(755, root, root) /usr/bin/mysql_explain_log -%attr(755, root, root) /usr/bin/mysql_fix_privilege_tables -%attr(755, root, root) /usr/bin/mysql_install_db -%attr(755, root, root) /usr/bin/mysql_secure_installation -%attr(755, root, root) /usr/bin/mysql_setpermission -%attr(755, root, root) /usr/bin/mysql_zap -%attr(755, root, root) /usr/bin/mysqlbug -%attr(755, root, root) /usr/bin/mysqld_multi -%attr(755, root, root) /usr/bin/mysqld_safe -%attr(755, root, root) /usr/bin/mysqlhotcopy -%attr(755, root, root) /usr/bin/mysqltest -%attr(755, root, root) /usr/bin/pack_isam -%attr(755, root, root) /usr/bin/perror -%attr(755, root, root) /usr/bin/replace -%attr(755, root, root) /usr/bin/resolve_stack_dump -%attr(755, root, root) /usr/bin/resolveip -%attr(755, root, root) /usr/bin/safe_mysqld +%attr(755, root, root) %{_bindir}/isamchk +%attr(755, root, root) %{_bindir}/isamlog +%attr(755, root, root) %{_bindir}/my_print_defaults +%attr(755, root, root) %{_bindir}/myisamchk +%attr(755, root, root) %{_bindir}/myisamlog +%attr(755, root, root) %{_bindir}/myisampack +%attr(755, root, root) %{_bindir}/mysql_convert_table_format +%attr(755, root, root) %{_bindir}/mysql_explain_log +%attr(755, root, root) %{_bindir}/mysql_fix_privilege_tables +%attr(755, root, root) %{_bindir}/mysql_install_db +%attr(755, root, root) %{_bindir}/mysql_secure_installation +%attr(755, root, root) %{_bindir}/mysql_setpermission +%attr(755, root, root) %{_bindir}/mysql_zap +%attr(755, root, root) %{_bindir}/mysqlbug +%attr(755, root, root) %{_bindir}/mysqld_multi +%attr(755, root, root) %{_bindir}/mysqld_safe +%attr(755, root, root) %{_bindir}/mysqlhotcopy +%attr(755, root, root) %{_bindir}/mysqltest +%attr(755, root, root) %{_bindir}/pack_isam +%attr(755, root, root) %{_bindir}/perror +%attr(755, root, root) %{_bindir}/replace +%attr(755, root, root) %{_bindir}/resolve_stack_dump +%attr(755, root, root) %{_bindir}/resolveip +%attr(755, root, root) %{_bindir}/safe_mysqld -%attr(755, root, root) /usr/sbin/mysqld -%attr(755, root, root) /usr/sbin/rcmysql -%attr(644, root, root) /usr/lib/mysql/mysqld.sym +%attr(755, root, root) %{_sbindir}/mysqld +%attr(755, root, root) %{_sbindir}/rcmysql +%attr(644, root, root) %{_libdir}/mysql/mysqld.sym -%attr(644, root, root) /etc/logrotate.d/mysql -%attr(755, root, root) /etc/init.d/mysql +%attr(644, root, root) %{_sysconfdir}/logrotate.d/mysql +%attr(755, root, root) %{_sysconfdir}/init.d/mysql -%attr(755, root, root) /usr/share/mysql/ +%attr(755, root, root) %{_datadir}/mysql/ %files client -%attr(755, root, root) /usr/bin/msql2mysql -%attr(755, root, root) /usr/bin/mysql -%attr(755, root, root) /usr/bin/mysql_find_rows -%attr(755, root, root) /usr/bin/mysql_waitpid -%attr(755, root, root) /usr/bin/mysqlaccess -%attr(755, root, root) /usr/bin/mysqladmin -%attr(755, root, root) /usr/bin/mysqlbinlog -%attr(755, root, root) /usr/bin/mysqlcheck -%attr(755, root, root) /usr/bin/mysqldump -%attr(755, root, root) /usr/bin/mysqlimport -%attr(755, root, root) /usr/bin/mysqlshow +%attr(755, root, root) %{_bindir}/msql2mysql +%attr(755, root, root) %{_bindir}/mysql +%attr(755, root, root) %{_bindir}/mysql_find_rows +%attr(755, root, root) %{_bindir}/mysql_waitpid +%attr(755, root, root) %{_bindir}/mysqlaccess +%attr(755, root, root) %{_bindir}/mysqladmin +%attr(755, root, root) %{_bindir}/mysqlbinlog +%attr(755, root, root) %{_bindir}/mysqlcheck +%attr(755, root, root) %{_bindir}/mysqldump +%attr(755, root, root) %{_bindir}/mysqlimport +%attr(755, root, root) %{_bindir}/mysqlshow %doc %attr(644, root, man) %{_mandir}/man1/mysql.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlaccess.1* @@ -508,45 +515,57 @@ fi %files devel %defattr(644 root, root) -%attr(755, root, root) /usr/bin/comp_err -%attr(755, root, root) /usr/bin/mysql_config -%dir %attr(755, root, root) /usr/include/mysql -%dir %attr(755, root, root) /usr/lib/mysql -/usr/include/mysql/* -/usr/lib/mysql/libdbug.a -/usr/lib/mysql/libheap.a -/usr/lib/mysql/libmerge.a -/usr/lib/mysql/libmyisam.a -/usr/lib/mysql/libmyisammrg.a -/usr/lib/mysql/libmysqlclient.a -/usr/lib/mysql/libmysqlclient.la -/usr/lib/mysql/libmysqlclient_r.a -/usr/lib/mysql/libmysqlclient_r.la -/usr/lib/mysql/libmystrings.a -/usr/lib/mysql/libmysys.a -/usr/lib/mysql/libnisam.a -/usr/lib/mysql/libvio.a +%attr(755, root, root) %{_bindir}/comp_err +%attr(755, root, root) %{_bindir}/mysql_config +%dir %attr(755, root, root) %{_includedir}/mysql +%dir %attr(755, root, root) %{_libdir}/mysql +%{_includedir}/mysql/* +%{_libdir}/mysql/libdbug.a +%{_libdir}/mysql/libheap.a +%{_libdir}/mysql/libmerge.a +%{_libdir}/mysql/libmyisam.a +%{_libdir}/mysql/libmyisammrg.a +%{_libdir}/mysql/libmysqlclient.a +%{_libdir}/mysql/libmysqlclient.la +%{_libdir}/mysql/libmysqlclient_r.a +%{_libdir}/mysql/libmysqlclient_r.la +%{_libdir}/mysql/libmystrings.a +%{_libdir}/mysql/libmysys.a +%{_libdir}/mysql/libnisam.a +%{_libdir}/mysql/libvio.a %files shared %defattr(755 root, root) # Shared libraries (omit for architectures that don't support them) -/usr/lib/*.so* +%{_libdir}/*.so* %files bench -%attr(-, root, root) /usr/share/sql-bench -%attr(-, root, root) /usr/share/mysql-test -%attr(755, root, root) /usr/bin/mysqlmanager -%attr(755, root, root) /usr/bin/mysqlmanager-pwgen -%attr(755, root, root) /usr/bin/mysqlmanagerc +%attr(-, root, root) %{_datadir}/sql-bench +%attr(-, root, root) %{_datadir}/mysql-test +%attr(755, root, root) %{_bindir}/mysqlmanager +%attr(755, root, root) %{_bindir}/mysqlmanager-pwgen +%attr(755, root, root) %{_bindir}/mysqlmanagerc %files Max -%attr(755, root, root) /usr/sbin/mysqld-max -%attr(644, root, root) /usr/lib/mysql/mysqld-max.sym +%attr(755, root, root) %{_sbindir}/mysqld-max +%attr(644, root, root) %{_libdir}/mysql/mysqld-max.sym %files embedded -%attr(644, root, root) /usr/lib/mysql/libmysqld.a +%attr(644, root, root) %{_libdir}/mysql/libmysqld.a %changelog +* Wed Jul 09 2003 Lenz Grimmer + +- removed the GIF Icon (file was not included in the sources anyway) +- removed unused variable %shared_lib_version +- do not run automake before building the standard binary + (should not be necessary) +- add server suffix '-standard' to standard binary (to be in line + with the binary tarball distributions) +- Use more RPM macros (_exec_prefix, _sbindir, _libdir, _sysconfdir, + _datadir, _includedir) throughout the spec file. +- allow overriding CC and CXX (required when building with other compilers) + * Fri May 16 2003 Lenz Grimmer - re-enabled RAID again From 82942ebf9d34c2fe024724dd9515aa9fc7284ebd Mon Sep 17 00:00:00 2001 From: "ram@mysql.r18.ru" <> Date: Thu, 10 Jul 2003 15:27:02 +0500 Subject: [PATCH 150/237] Fix for the bug #803. Now INTERVAL(NULL, N1, N2, ...) returns NULL. --- mysql-test/r/func_set.result | 3 +++ mysql-test/t/func_set.test | 1 + sql/item_cmpfunc.cc | 22 ++++++++++++---------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result index 5305c16c5d9..dfd7750adaf 100644 --- a/mysql-test/r/func_set.result +++ b/mysql-test/r/func_set.result @@ -25,3 +25,6 @@ find_in_set("","a,b,c") find_in_set("","a,b,c,") find_in_set("",",a,b,c") select find_in_set("abc","abc"),find_in_set("ab","abc"),find_in_set("abcd","abc"); find_in_set("abc","abc") find_in_set("ab","abc") find_in_set("abcd","abc") 1 0 0 +select interval(null, 1, 10, 100); +interval(null, 1, 10, 100) +NULL diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test index cb1aa543d43..81f561989d5 100644 --- a/mysql-test/t/func_set.test +++ b/mysql-test/t/func_set.test @@ -15,3 +15,4 @@ select export_set(9,"Y","N","-",5),export_set(9,"Y","N"),export_set(9,"Y","N","" select elt(2,1),field(NULL,"a","b","c"); select find_in_set("","a,b,c"),find_in_set("","a,b,c,"),find_in_set("",",a,b,c"); select find_in_set("abc","abc"),find_in_set("ab","abc"),find_in_set("abcd","abc"); +select interval(null, 1, 10, 100); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5d47fa302f3..731f9b61438 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -311,7 +311,7 @@ void Item_func_interval::split_sum_func(List &fields) } /* - return -1 if null value, + return NULL if null value, 0 if lower than lowest 1 - arg_count if between args[n] and args[n+1] arg_count+1 if higher than biggest argument @@ -319,26 +319,28 @@ void Item_func_interval::split_sum_func(List &fields) longlong Item_func_interval::val_int() { - double value=item->val(); + double value= item->val(); if (item->null_value) - return -1; // -1 if null /* purecov: inspected */ + { + null_value= 1; + return -1; + } if (intervals) { // Use binary search to find interval - uint start,end; - start=0; end=arg_count-1; + uint start= 0, end= arg_count - 1; while (start != end) { - uint mid=(start+end+1)/2; + uint mid= (start + end + 1) / 2; if (intervals[mid] <= value) - start=mid; + start= mid; else - end=mid-1; + end= mid - 1; } - return (value < intervals[start]) ? 0 : start+1; + return (value < intervals[start]) ? 0 : start + 1; } if (args[0]->val() > value) return 0; - for (uint i=1 ; i < arg_count ; i++) + for (uint i= 1; i < arg_count; i++) { if (args[i]->val() > value) return i; From 2ca501f7ea66e862ad4b064a175a83bad930f8ba Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Thu, 10 Jul 2003 16:03:29 +0200 Subject: [PATCH 151/237] Fix for BUG#812 "mysqlhotcopy fails to copy tables but does not indicate a failure" ("does not indicate a failure"); this is about "mysqlhotcopy fails to copy tables". --- .../t/rpl_error_ignored_table-slave.opt | 2 +- scripts/mysqlhotcopy.sh | 68 +++++++++++++------ 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/mysql-test/t/rpl_error_ignored_table-slave.opt b/mysql-test/t/rpl_error_ignored_table-slave.opt index 544ecb2959b..0d3485f9e25 100644 --- a/mysql-test/t/rpl_error_ignored_table-slave.opt +++ b/mysql-test/t/rpl_error_ignored_table-slave.opt @@ -1 +1 @@ ---replicate-ignore-table=test.t1 \ No newline at end of file +--replicate-ignore-table=test.t1 diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh index 98a5c5b9f85..f23955da06a 100644 --- a/scripts/mysqlhotcopy.sh +++ b/scripts/mysqlhotcopy.sh @@ -569,22 +569,22 @@ sub copy_files { print "Copying ".@$files." files...\n" unless $opt{quiet}; if ($method =~ /^s?cp\b/) { # cp or scp with optional flags - my @cp = ($method); + my $cp = $method; # add option to preserve mod time etc of copied files # not critical, but nice to have - push @cp, "-p" if $^O =~ m/^(solaris|linux|freebsd|darwin)$/; + $cp.= " -p" if $^O =~ m/^(solaris|linux|freebsd|darwin)$/; # add recursive option for scp - push @cp, "-r" if $^O =~ /m^(solaris|linux|freebsd|darwin)$/ && $method =~ /^scp\b/; + $cp.= " -r" if $^O =~ /m^(solaris|linux|freebsd|darwin)$/ && $method =~ /^scp\b/; my @non_raid = map { "'$_'" } grep { ! m:/\d{2}/[^/]+$: } @$files; # add files to copy and the destination directory - safe_system( @cp, @non_raid, "'$target'" ) if (@non_raid); + safe_system( $cp, @non_raid, "'$target'" ) if (@non_raid); foreach my $rd ( @$raid_dirs ) { my @raid = map { "'$_'" } grep { m:$rd/: } @$files; - safe_system( @cp, @raid, "'$target'/$rd" ) if ( @raid ); + safe_system( $cp, @raid, "'$target'/$rd" ) if ( @raid ); } } else @@ -646,24 +646,52 @@ sub copy_index } -sub safe_system -{ - my @cmd= @_; +sub safe_system { + my @sources= @_; + my $method= shift @sources; + my $target= pop @sources; + ## @sources = list of source file names - if ( $opt{dryrun} ) - { - print "@cmd\n"; - return; + ## We have to deal with very long command lines, otherwise they may generate + ## "Argument list too long". + ## With 10000 tables the command line can be around 1MB, much more than 128kB + ## which is the common limit on Linux (can be read from + ## /usr/src/linux/include/linux/binfmts.h + ## see http://www.linuxjournal.com/article.php?sid=6060). + + my $chunk_limit= 100 * 1024; # 100 kB + my @chunk= (); + my $chunk_length= 0; + foreach (@sources) { + push @chunk, $_; + $chunk_length+= length($_); + if ($chunk_length > $chunk_limit) { + safe_simple_system($method, @chunk, $target); + @chunk=(); + $chunk_length= 0; + } } + if ($chunk_length > 0) { # do not forget last small chunk + safe_simple_system($method, @chunk, $target); + } +} - ## for some reason system fails but backticks works ok for scp... - print "Executing '@cmd'\n" if $opt{debug}; - my $cp_status = system "@cmd > /dev/null"; - if ($cp_status != 0) { - warn "Executing command failed ($cp_status). Trying backtick execution...\n"; - ## try something else - `@cmd` || die "Error: @cmd failed ($?) while copying files.\n"; - } +sub safe_simple_system { + my @cmd= @_; + + if ( $opt{dryrun} ) { + print "@cmd\n"; + } + else { + ## for some reason system fails but backticks works ok for scp... + print "Executing '@cmd'\n" if $opt{debug}; + my $cp_status = system "@cmd > /dev/null"; + if ($cp_status != 0) { + warn "Executing command failed ($cp_status). Trying backtick execution...\n"; + ## try something else + `@cmd` || die "Error: @cmd failed ($?) while copying files.\n"; + } + } } sub retire_directory { From 4ca9718375f3bc69135009fa66a75af3c33e81e4 Mon Sep 17 00:00:00 2001 From: "ram@mysql.r18.ru" <> Date: Fri, 11 Jul 2003 14:17:18 +0500 Subject: [PATCH 152/237] Fix for the bug #801: create table t1 select x'41'; doesn't work --- mysql-test/r/create.result | 2 ++ mysql-test/t/create.test | 7 +++++++ sql/sql_select.cc | 1 + 3 files changed, 10 insertions(+) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 2e2aa41c671..e6192eb6ccb 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -176,3 +176,5 @@ Column 'k1' cannot be null insert into t1 values (NULL, NULL); Column 'k1' cannot be null drop table t1; +create table t1 select x'4132'; +drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 86c3f6be0f5..d46807f1dca 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -127,3 +127,10 @@ insert into t1 values ("a", 1), ("b", 2); !$1048 insert into t1 values (NULL, 3); !$1048 insert into t1 values (NULL, NULL); drop table t1; + +# +# Bug # 801 +# + +create table t1 select x'4132'; +drop table t1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 80e329a7f03..4008bf75f01 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3664,6 +3664,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, case Item::STRING_ITEM: case Item::REF_ITEM: case Item::NULL_ITEM: + case Item::VARBIN_ITEM: { bool maybe_null=item->maybe_null; Field *new_field; From fbebac9a484bf08a6f557c40bd502045db6d2356 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 11 Jul 2003 14:26:44 +0200 Subject: [PATCH 153/237] Fix for BUG#791: a safer way of initing the mutexes in MYSQL_LOG. is_open() is now always thread-safe. See each file for details. --- sql/handler.cc | 4 +- sql/item_func.cc | 2 +- sql/log.cc | 316 ++++++++++++++++++++++--------------------- sql/log_event.cc | 10 +- sql/mysqld.cc | 13 ++ sql/repl_failsafe.cc | 2 +- sql/slave.cc | 14 +- sql/sql_base.cc | 2 +- sql/sql_class.h | 11 +- sql/sql_db.cc | 4 +- sql/sql_delete.cc | 6 +- sql/sql_insert.cc | 8 +- sql/sql_load.cc | 8 +- sql/sql_parse.cc | 4 +- sql/sql_rename.cc | 2 +- sql/sql_repl.cc | 14 +- sql/sql_table.cc | 10 +- sql/sql_update.cc | 4 +- 18 files changed, 234 insertions(+), 200 deletions(-) diff --git a/sql/handler.cc b/sql/handler.cc index 4ea5bc0e9f5..0c95dbc4b31 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -346,7 +346,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) bool transaction_commited= 0; /* Update the binary log if we have cached some queries */ - if (trans == &thd->transaction.all && mysql_bin_log.is_open() && + if (trans == &thd->transaction.all && mysql_bin_log.is_open(1) && my_b_tell(&thd->transaction.trans_log)) { mysql_bin_log.write(thd, &thd->transaction.trans_log); @@ -385,7 +385,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) if (transaction_commited && thd->transaction.changed_tables) query_cache.invalidate(thd->transaction.changed_tables); #endif /*HAVE_QUERY_CACHE*/ - if (error && trans == &thd->transaction.all && mysql_bin_log.is_open()) + if (error && trans == &thd->transaction.all && mysql_bin_log.is_open(1)) sql_print_error("Error: Got error during commit; Binlog is not up to date!"); thd->variables.tx_isolation=thd->session_tx_isolation; if (operation_done) diff --git a/sql/item_func.cc b/sql/item_func.cc index 8e9677cc459..f7b47736f33 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1504,7 +1504,7 @@ void item_user_lock_free(void) void item_user_lock_release(ULL *ull) { ull->locked=0; - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { char buf[256]; String tmp(buf,sizeof(buf)); diff --git a/sql/log.cc b/sql/log.cc index c24c2f2e39b..7b35433b830 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -82,12 +82,14 @@ static int find_uniq_filename(char *name) MYSQL_LOG::MYSQL_LOG() :bytes_written(0), last_time(0), query_start(0), name(0), - file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0), + file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), no_rotate(0), need_start_event(1) { /* - We don't want to intialize LOCK_Log here as the thread system may - not have been initailized yet. We do it instead at 'open'. + We don't want to initialize LOCK_Log here as such initialization depends on + safe_mutex (when using safe_mutex) which depends on MY_INIT(), which is + called only in main(). Doing initialization here would make it happen before + main(). */ index_file_name[0] = 0; bzero((char*) &log_file,sizeof(log_file)); @@ -100,18 +102,35 @@ MYSQL_LOG::~MYSQL_LOG() cleanup(); } -void MYSQL_LOG::cleanup() +void MYSQL_LOG::cleanup() /* this is called only once */ { - if (inited) - { - close(1); - inited= 0; - (void) pthread_mutex_destroy(&LOCK_log); - (void) pthread_mutex_destroy(&LOCK_index); - (void) pthread_cond_destroy(&update_cond); - } + close(1); + (void) pthread_mutex_destroy(&LOCK_log); + (void) pthread_mutex_destroy(&LOCK_index); + (void) pthread_cond_destroy(&update_cond); } +bool MYSQL_LOG::is_open(bool need_mutex) +{ + /* + Since MySQL 4.0.14, LOCK_log is always inited: + * for log/update_log/slow_log/bin_log which are global objects, this is done in + main(), even if the server does not use these logs. + * for relay_log which belongs to rli which belongs to active_mi, this is + done in the constructor of rli. + In older versions, we were never 100% sure that LOCK_log was inited, which + was a problem. + */ + if (need_mutex) + { + pthread_mutex_lock(&LOCK_log); + bool res= (log_type != LOG_CLOSED); + pthread_mutex_unlock(&LOCK_log); + return res; + } + else + return (log_type != LOG_CLOSED); +} int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) { @@ -142,16 +161,15 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, no_auto_events = no_auto_events_arg; max_size=max_size_arg; DBUG_PRINT("info",("log_type: %d max_size: %lu", log_type, max_size)); - if (!inited) - { - inited= 1; - (void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW); - (void) pthread_cond_init(&update_cond, 0); - } DBUG_VOID_RETURN; } +void MYSQL_LOG::init_pthread_objects() +{ + (void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW); + (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW); + (void) pthread_cond_init(&update_cond, 0); +} /* Open a (new) log file. @@ -182,8 +200,6 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, last_time=query_start=0; write_error=0; - if (!inited && log_type_arg == LOG_BIN && *fn_ext(log_name)) - no_rotate = 1; init(log_type_arg,io_cache_type_arg,no_auto_events_arg,max_size); if (!(name=my_strdup(log_name,MYF(MY_WME)))) @@ -631,7 +647,7 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) Assume that we have previously read the first log and stored it in rli->relay_log_name */ - DBUG_ASSERT(is_open()); + DBUG_ASSERT(is_open(1)); DBUG_ASSERT(rli->slave_running == 1); DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name)); DBUG_ASSERT(rli->linfo.index_file_offset == @@ -770,14 +786,11 @@ err: void MYSQL_LOG::make_log_name(char* buf, const char* log_ident) { - if (inited) // QQ When is this not true ? - { - uint dir_len = dirname_length(log_file_name); - if (dir_len > FN_REFLEN) - dir_len=FN_REFLEN-1; - strnmov(buf, log_file_name, dir_len); - strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len); - } + uint dir_len = dirname_length(log_file_name); + if (dir_len > FN_REFLEN) + dir_len=FN_REFLEN-1; + strnmov(buf, log_file_name, dir_len); + strmake(buf+dir_len, log_ident, FN_REFLEN - dir_len); } @@ -787,7 +800,7 @@ void MYSQL_LOG::make_log_name(char* buf, const char* log_ident) bool MYSQL_LOG::is_active(const char *log_file_name_arg) { - return inited && !strcmp(log_file_name, log_file_name_arg); + return !strcmp(log_file_name, log_file_name_arg); } @@ -809,7 +822,7 @@ void MYSQL_LOG::new_file(bool need_lock) enum_log_type save_log_type; DBUG_ENTER("MYSQL_LOG::new_file"); - if (!is_open()) + if (!is_open(need_lock)) { DBUG_PRINT("info",("log is closed")); DBUG_VOID_RETURN; @@ -876,7 +889,9 @@ void MYSQL_LOG::new_file(bool need_lock) name=0; // Don't free name close(); - // TODO: at this place is_open() will see the log closed, which is BUG#791. + /* + Note that at this point, log_type == LOG_CLOSED (important for is_open()). + */ open(old_name, save_log_type, new_name_ptr, index_file_name, io_cache_type, no_auto_events, max_size); @@ -967,12 +982,11 @@ err: bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, const char *format,...) { - if (is_open() && (what_to_log & (1L << (uint) command))) + if (what_to_log & (1L << (uint) command)) { int error=0; VOID(pthread_mutex_lock(&LOCK_log)); - /* Test if someone closed between the is_open test and lock */ if (is_open()) { time_t skr; @@ -1055,14 +1069,13 @@ bool MYSQL_LOG::write(Log_event* event_info) bool error=0; DBUG_ENTER("MYSQL_LOG::write(event)"); - if (!inited) // Can't use mutex if not init - { - DBUG_PRINT("error",("not initied")); - DBUG_RETURN(0); - } pthread_mutex_lock(&LOCK_log); - /* In most cases this is only called if 'is_open()' is true */ + /* + In most cases this is only called if 'is_open()' is true; in fact this is + mostly called if is_open() *was* true a few instructions before, but it + could have changed since. + */ if (is_open()) { bool should_rotate = 0; @@ -1380,120 +1393,117 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, time_t query_start_arg) { bool error=0; + time_t current_time; + VOID(pthread_mutex_lock(&LOCK_log)); if (is_open()) - { - time_t current_time; - VOID(pthread_mutex_lock(&LOCK_log)); - if (is_open()) - { // Safety agains reopen - int tmp_errno=0; - char buff[80],*end; - end=buff; - if (!(thd->options & OPTION_UPDATE_LOG) && - (thd->master_access & SUPER_ACL)) + { // Safety agains reopen + int tmp_errno=0; + char buff[80],*end; + end=buff; + if (!(thd->options & OPTION_UPDATE_LOG) && + (thd->master_access & SUPER_ACL)) + { + VOID(pthread_mutex_unlock(&LOCK_log)); + return 0; + } + if ((specialflag & SPECIAL_LONG_LOG_FORMAT) || query_start_arg) + { + current_time=time(NULL); + if (current_time != last_time) { - VOID(pthread_mutex_unlock(&LOCK_log)); - return 0; + last_time=current_time; + struct tm tm_tmp; + struct tm *start; + localtime_r(¤t_time,&tm_tmp); + start=&tm_tmp; + /* Note that my_b_write() assumes it knows the length for this */ + sprintf(buff,"# Time: %02d%02d%02d %2d:%02d:%02d\n", + start->tm_year % 100, + start->tm_mon+1, + start->tm_mday, + start->tm_hour, + start->tm_min, + start->tm_sec); + if (my_b_write(&log_file, (byte*) buff,24)) + tmp_errno=errno; } - if ((specialflag & SPECIAL_LONG_LOG_FORMAT) || query_start_arg) + if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n", + thd->priv_user, + thd->user, + thd->host ? thd->host : "", + thd->ip ? thd->ip : "") == (uint) -1) + tmp_errno=errno; + } + if (query_start_arg) + { + /* For slow query log */ + if (my_b_printf(&log_file, + "# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n", + (ulong) (current_time - query_start_arg), + (ulong) (thd->time_after_lock - query_start_arg), + (ulong) thd->sent_row_count, + (ulong) thd->examined_row_count) == (uint) -1) + tmp_errno=errno; + } + if (thd->db && strcmp(thd->db,db)) + { // Database changed + if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1) + tmp_errno=errno; + strmov(db,thd->db); + } + if (thd->last_insert_id_used) + { + end=strmov(end,",last_insert_id="); + end=longlong10_to_str((longlong) thd->current_insert_id,end,-10); + } + // Save value if we do an insert. + if (thd->insert_id_used) + { + if (specialflag & SPECIAL_LONG_LOG_FORMAT) { - current_time=time(NULL); - if (current_time != last_time) - { - last_time=current_time; - struct tm tm_tmp; - struct tm *start; - localtime_r(¤t_time,&tm_tmp); - start=&tm_tmp; - /* Note that my_b_write() assumes it knows the length for this */ - sprintf(buff,"# Time: %02d%02d%02d %2d:%02d:%02d\n", - start->tm_year % 100, - start->tm_mon+1, - start->tm_mday, - start->tm_hour, - start->tm_min, - start->tm_sec); - if (my_b_write(&log_file, (byte*) buff,24)) - tmp_errno=errno; - } - if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n", - thd->priv_user, - thd->user, - thd->host ? thd->host : "", - thd->ip ? thd->ip : "") == (uint) -1) - tmp_errno=errno; - } - if (query_start_arg) - { - /* For slow query log */ - if (my_b_printf(&log_file, - "# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n", - (ulong) (current_time - query_start_arg), - (ulong) (thd->time_after_lock - query_start_arg), - (ulong) thd->sent_row_count, - (ulong) thd->examined_row_count) == (uint) -1) - tmp_errno=errno; - } - if (thd->db && strcmp(thd->db,db)) - { // Database changed - if (my_b_printf(&log_file,"use %s;\n",thd->db) == (uint) -1) - tmp_errno=errno; - strmov(db,thd->db); - } - if (thd->last_insert_id_used) - { - end=strmov(end,",last_insert_id="); - end=longlong10_to_str((longlong) thd->current_insert_id,end,-10); - } - // Save value if we do an insert. - if (thd->insert_id_used) - { - if (specialflag & SPECIAL_LONG_LOG_FORMAT) - { - end=strmov(end,",insert_id="); - end=longlong10_to_str((longlong) thd->last_insert_id,end,-10); - } - } - if (thd->query_start_used) - { - if (query_start_arg != thd->query_start()) - { - query_start_arg=thd->query_start(); - end=strmov(end,",timestamp="); - end=int10_to_str((long) query_start_arg,end,10); - } - } - if (end != buff) - { - *end++=';'; - *end='\n'; - if (my_b_write(&log_file, (byte*) "SET ",4) || - my_b_write(&log_file, (byte*) buff+1,(uint) (end-buff))) - tmp_errno=errno; - } - if (!query) - { - end=strxmov(buff, "# administrator command: ", - command_name[thd->command], NullS); - query_length=(ulong) (end-buff); - query=buff; - } - if (my_b_write(&log_file, (byte*) query,query_length) || - my_b_write(&log_file, (byte*) ";\n",2) || - flush_io_cache(&log_file)) - tmp_errno=errno; - if (tmp_errno) - { - error=1; - if (! write_error) - { - write_error=1; - sql_print_error(ER(ER_ERROR_ON_WRITE),name,error); - } + end=strmov(end,",insert_id="); + end=longlong10_to_str((longlong) thd->last_insert_id,end,-10); + } + } + if (thd->query_start_used) + { + if (query_start_arg != thd->query_start()) + { + query_start_arg=thd->query_start(); + end=strmov(end,",timestamp="); + end=int10_to_str((long) query_start_arg,end,10); + } + } + if (end != buff) + { + *end++=';'; + *end='\n'; + if (my_b_write(&log_file, (byte*) "SET ",4) || + my_b_write(&log_file, (byte*) buff+1,(uint) (end-buff))) + tmp_errno=errno; + } + if (!query) + { + end=strxmov(buff, "# administrator command: ", + command_name[thd->command], NullS); + query_length=(ulong) (end-buff); + query=buff; + } + if (my_b_write(&log_file, (byte*) query,query_length) || + my_b_write(&log_file, (byte*) ";\n",2) || + flush_io_cache(&log_file)) + tmp_errno=errno; + if (tmp_errno) + { + error=1; + if (! write_error) + { + write_error=1; + sql_print_error(ER(ER_ERROR_ON_WRITE),name,error); } } - VOID(pthread_mutex_unlock(&LOCK_log)); } + VOID(pthread_mutex_unlock(&LOCK_log)); return error; } @@ -1591,14 +1601,12 @@ void MYSQL_LOG::set_max_size(ulong max_size_arg) uses the old_max_size argument, so max_size_arg has been overwritten and it's like if the SET command was never run. */ + DBUG_ENTER("MYSQL_LOG::set_max_size"); + pthread_mutex_lock(&LOCK_log); if (is_open()) - { - pthread_mutex_lock(&LOCK_log); - pthread_mutex_lock(&LOCK_index); max_size= max_size_arg; - pthread_mutex_unlock(&LOCK_index); - pthread_mutex_unlock(&LOCK_log); - } + pthread_mutex_unlock(&LOCK_log); + DBUG_VOID_RETURN; } /* diff --git a/sql/log_event.cc b/sql/log_event.cc index a6d2abbf894..5a0a243c57b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2167,7 +2167,7 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli) int Slave_log_event::exec_event(struct st_relay_log_info* rli) { - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) mysql_bin_log.write(this); return Log_event::exec_event(rli); } @@ -2217,7 +2217,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) slave_print_error(rli,my_errno, "Write to '%s' failed", fname_buf); goto err; } - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) mysql_bin_log.write(this); error=0; // Everything is ok @@ -2237,7 +2237,7 @@ int Delete_file_log_event::exec_event(struct st_relay_log_info* rli) (void) my_delete(fname, MYF(MY_WME)); memcpy(p, ".info", 6); (void) my_delete(fname, MYF(MY_WME)); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) mysql_bin_log.write(this); return Log_event::exec_event(rli); } @@ -2260,7 +2260,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli) slave_print_error(rli,my_errno, "Write to '%s' failed", fname); goto err; } - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) mysql_bin_log.write(this); error=0; @@ -2319,7 +2319,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) (void) my_delete(fname, MYF(MY_WME)); memcpy(p, ".data", 6); (void) my_delete(fname, MYF(MY_WME)); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) mysql_bin_log.write(this); error = 0; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1ede1a87153..c21d71466ba 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1972,6 +1972,8 @@ bool open_log(MYSQL_LOG *log, const char *hostname, strmake(tmp,opt_name,min(length,FN_REFLEN)); opt_name=tmp; } + if (*fn_ext(opt_name)) + log->set_no_rotate(1); } return log->open(opt_name, type, 0, index_file_name, (read_append) ? SEQ_READ_APPEND : WRITE_CACHE, @@ -2019,6 +2021,17 @@ int main(int argc, char **argv) } #endif + /* + Init mutexes for the global MYSQL_LOG objects. + As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of + global MYSQL_LOGs in their constructors, because then they would be inited + before MY_INIT(). So we do it here. + */ + mysql_log.init_pthread_objects(); + mysql_update_log.init_pthread_objects(); + mysql_slow_log.init_pthread_objects(); + mysql_bin_log.init_pthread_objects(); + if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0) strmov(glob_hostname,"mysql"); strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5); diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 1552b3994e9..6f404d4b958 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -265,7 +265,7 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) LINT_INIT(cmp_res); DBUG_ENTER("translate_master"); - if (!mysql_bin_log.is_open()) + if (!mysql_bin_log.is_open(1)) { strmov(errmsg,"Binary log is not open"); DBUG_RETURN(1); diff --git a/sql/slave.cc b/sql/slave.cc index e0ca4f1ad7a..557e288539b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1736,6 +1736,7 @@ st_relay_log_info::st_relay_log_info() pthread_cond_init(&start_cond, NULL); pthread_cond_init(&stop_cond, NULL); pthread_cond_init(&log_space_cond, NULL); + relay_log.init_pthread_objects(); } @@ -3443,14 +3444,18 @@ void rotate_relay_log(MASTER_INFO* mi) { DBUG_ENTER("rotate_relay_log"); RELAY_LOG_INFO* rli= &mi->rli; - /* If this server is not a slave (or RESET SLAVE has just been run) */ + + lock_slave_threads(mi); + pthread_mutex_lock(&rli->data_lock); + /* + We need to test inited because otherwise, new_file() will attempt to lock + LOCK_log, which may not be inited (if we're not a slave). + */ if (!rli->inited) { DBUG_PRINT("info", ("rli->inited == 0")); - DBUG_VOID_RETURN; + goto end; } - lock_slave_threads(mi); - pthread_mutex_lock(&rli->data_lock); /* If the relay log is closed, new_file() will do nothing. */ rli->relay_log.new_file(1); @@ -3469,6 +3474,7 @@ void rotate_relay_log(MASTER_INFO* mi) 0 as they probably have been harvested. */ rli->relay_log.harvest_bytes_written(&rli->log_space_total); +end: pthread_mutex_unlock(&rli->data_lock); unlock_slave_threads(mi); DBUG_VOID_RETURN; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 43718e5d93b..217597ccda5 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -574,7 +574,7 @@ void close_temporary_tables(THD *thd) next=table->next; close_temporary(table); } - if (query && found_user_tables && mysql_bin_log.is_open()) + if (query && found_user_tables && mysql_bin_log.is_open(1)) { /* The -1 is to remove last ',' */ Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0); diff --git a/sql/sql_class.h b/sql/sql_class.h index 71b943b5d26..cd622520df3 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -61,6 +61,11 @@ class Log_event; class MYSQL_LOG { private: + /* + LOCK_log is inited by MYSQL_LOG::init(), so one should try to lock it only + if he is sure MYSQL_LOG::init() has been called (i.e. if 'inited' is true). + Same for LOCK_index. + */ pthread_mutex_t LOCK_log, LOCK_index; pthread_cond_t update_cond; ulonglong bytes_written; @@ -80,7 +85,7 @@ class MYSQL_LOG { */ volatile enum_log_type log_type; enum cache_type io_cache_type; - bool write_error,inited; + bool write_error; bool no_rotate; bool need_start_event; bool no_auto_events; // for relay binlog @@ -123,6 +128,7 @@ public: void init(enum_log_type log_type_arg, enum cache_type io_cache_type_arg, bool no_auto_events_arg, ulong max_size); + void init_pthread_objects(); void cleanup(); bool open(const char *log_name,enum_log_type log_type, const char *new_name, const char *index_file_name_arg, @@ -158,8 +164,8 @@ public: int find_next_log(LOG_INFO* linfo, bool need_mutex); int get_current_log(LOG_INFO* linfo); uint next_file_id(); + bool is_open(bool need_mutex=0); - inline bool is_open() { return log_type != LOG_CLOSED; } inline char* get_index_fname() { return index_file_name;} inline char* get_log_fname() { return log_file_name; } inline pthread_mutex_t* get_log_lock() { return &LOCK_log; } @@ -169,6 +175,7 @@ public: inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);} inline IO_CACHE *get_index_file() { return &index_file;} inline uint32 get_open_count() { return open_count; } + inline void set_no_rotate(bool no_rotate_arg) {no_rotate= no_rotate_arg;} }; /* character conversion tables */ diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 6251b1ec624..6045955334c 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -84,7 +84,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) } { mysql_update_log.write(thd,thd->query, thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); @@ -174,7 +174,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) thd->query= path; } mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 45acbaaa7ef..8b81e57d419 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -172,7 +172,7 @@ cleanup: if (deleted && (error <= 0 || !transactional_table)) { mysql_update_log.write(thd,thd->query, thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); @@ -476,7 +476,7 @@ bool multi_delete::send_eof() if (deleted && (error <= 0 || normal_tables)) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); @@ -588,7 +588,7 @@ end: if (!error) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, thd->tmp_table); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 167ccf974c7..f94963f2570 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -308,7 +308,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, if ((info.copied || info.deleted) && (error <= 0 || !transactional_table)) { mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); @@ -1143,7 +1143,7 @@ bool delayed_insert::handle_inserts(void) { int error; uint max_rows; - bool using_ignore=0, using_bin_log=mysql_bin_log.is_open(); + bool using_ignore=0, using_bin_log=mysql_bin_log.is_open(1); delayed_row *row; DBUG_ENTER("handle_inserts"); @@ -1361,7 +1361,7 @@ void select_insert::send_error(uint errcode,const char *err) if (last_insert_id) thd->insert_id(last_insert_id); // For binary log mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, table->file->has_transactions()); @@ -1387,7 +1387,7 @@ bool select_insert::send_eof() thd->insert_id(last_insert_id); // For binary log /* Write to binlog before commiting transaction */ mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, table->file->has_transactions()); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index ee573672c35..7a20fbfd928 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -219,7 +219,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, DBUG_RETURN(-1); // Can't allocate buffers } - if (!opt_old_rpl_compat && mysql_bin_log.is_open()) + if (!opt_old_rpl_compat && mysql_bin_log.is_open(1)) { lf_info.thd = thd; lf_info.ex = ex; @@ -281,7 +281,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { if (transactional_table) ha_autocommit_or_rollback(thd,error); - if (!opt_old_rpl_compat && mysql_bin_log.is_open()) + if (!opt_old_rpl_compat && mysql_bin_log.is_open(1)) { if (lf_info.wrote_create_file) { @@ -315,7 +315,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if (!log_delayed) thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { if (opt_old_rpl_compat) { @@ -607,7 +607,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term, cache.read_function = _my_b_net_read; need_end_io_cache = 1; - if (!opt_old_rpl_compat && mysql_bin_log.is_open()) + if (!opt_old_rpl_compat && mysql_bin_log.is_open(1)) cache.pre_read = cache.pre_close = (IO_CACHE_CALLBACK) log_loaded_block; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 70c0f772d7d..a32dce4d704 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2432,7 +2432,7 @@ mysql_execute_command(void) lex->sql_command == SQLCOM_REVOKE))) { mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); @@ -2452,7 +2452,7 @@ mysql_execute_command(void) if (!res) { mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index d7e998264f3..cfc6e5b0721 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -80,7 +80,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) if (!error) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index e775a5d712e..a671facdc08 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -269,7 +269,7 @@ int purge_master_logs(THD* thd, const char* to_log) const char* errmsg = 0; int res; - if (!mysql_bin_log.is_open()) + if (!mysql_bin_log.is_open(1)) goto end; mysql_bin_log.make_log_name(search_file_name, to_log); @@ -335,7 +335,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, } #endif - if (!mysql_bin_log.is_open()) + if (!mysql_bin_log.is_open(1)) { errmsg = "Binary log is not open"; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; @@ -972,7 +972,7 @@ int change_master(THD* thd, MASTER_INFO* mi) int reset_master(THD* thd) { - if (!mysql_bin_log.is_open()) + if (!mysql_bin_log.is_open(1)) { my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(ME_BELL+ME_WAITTANG)); return 1; @@ -1010,7 +1010,7 @@ int show_binlog_events(THD* thd) if (send_fields(thd, field_list, 1)) DBUG_RETURN(-1); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { LEX_MASTER_INFO *lex_mi = &thd->lex.mi; ha_rows event_count, limit_start, limit_end; @@ -1110,7 +1110,7 @@ int show_binlog_info(THD* thd) String* packet = &thd->packet; packet->length(0); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { LOG_INFO li; mysql_bin_log.get_current_log(&li); @@ -1128,7 +1128,7 @@ int show_binlog_info(THD* thd) /* - Send a lost of all binary logs to client + Send a list of all binary logs to client SYNOPSIS show_binlogs() @@ -1148,7 +1148,7 @@ int show_binlogs(THD* thd) String *packet = &thd->packet; uint length; - if (!mysql_bin_log.is_open()) + if (!mysql_bin_log.is_open(1)) { //TODO: Replace with ER() error message send_error(net, 0, "You are not using binary logging"); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index cf430aec35d..2d024ded5db 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -235,7 +235,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (!dont_log_query) { mysql_update_log.write(thd, thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, tmp_table_deleted && !some_tables_deleted); @@ -766,7 +766,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { // Must be written before unlock mysql_update_log.write(thd,thd->query, thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, test(create_info->options & @@ -1548,7 +1548,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!error) { mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); @@ -1918,7 +1918,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } mysql_update_log.write(thd, thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); @@ -2050,7 +2050,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } thd->proc_info="end"; mysql_update_log.write(thd, thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 3179c8e0f24..42ba00d3ad5 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -317,7 +317,7 @@ int mysql_update(THD *thd, if (updated && (error <= 0 || !transactional_table)) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); @@ -933,7 +933,7 @@ bool multi_update::send_eof() if (updated && (local_error <= 0 || !trans_safe)) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open()) + if (mysql_bin_log.is_open(1)) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); From 9a9d7c6bc122058c34dc3f7559a079fea3d0d9f5 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Fri, 11 Jul 2003 18:24:13 +0200 Subject: [PATCH 154/237] - fixed a bug in Bootstrap script: simply searching for the last tagged ChangeSet was not sufficient to get the full ChangeLog between two released versions (when using "--changelog=last") as merging between trees also merges the BK tags. Now we explicitely search for the last tagged ChangeSet that matches our major+minor version number, which should match the last ChangeSet used for the previous release. --- Build-tools/Bootstrap | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index 9f5fc37736d..b16218cfc3b 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -43,6 +43,7 @@ $opt_test= undef; $opt_skip_check= undef; $opt_skip_manual= undef; $version= "unknown"; +$major=$minor=$release=0; GetOptions( "build-command|b=s", @@ -149,6 +150,7 @@ if (!$opt_dry_run) { m/^AM_INIT_AUTOMAKE\(mysql, ([1-9]\.[0-9]{1,2}\.[0-9]{1,2}.*)\)/; $version= $1; + ($major, $minor, $release) = split(/\./,$version); } &logger("Found version string: $version"); @@ -218,7 +220,7 @@ if (defined $opt_changelog) { if (!$opt_revision) { - $revision= `bk changes -t -d':REV:' -n $REPO | head -1`; + $revision= `bk changes -t -d':REV:::TAG:' -n $REPO | grep mysql-$major-$minor | head -1 | cut -f1 -d ":"`; } else { From c1685efe6c2bfa3d239f8c19bdb2f4295245f4c7 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Fri, 11 Jul 2003 19:32:29 +0200 Subject: [PATCH 155/237] - fixed a typo in previous push --- Build-tools/Bootstrap | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index b16218cfc3b..20cd5a089bd 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -38,6 +38,7 @@ $opt_export_only= undef; $opt_help= $opt_verbose= 0; $opt_log= undef; $opt_mail= ""; +$opt_revision= undef; $opt_suffix= ""; $opt_test= undef; $opt_skip_check= undef; @@ -220,7 +221,7 @@ if (defined $opt_changelog) { if (!$opt_revision) { - $revision= `bk changes -t -d':REV:::TAG:' -n $REPO | grep mysql-$major-$minor | head -1 | cut -f1 -d ":"`; + $revision= `bk changes -t -d':REV:::TAG:' -n $REPO | grep mysql-$major.$minor | head -1 | cut -f1 -d ":"`; } else { From 8fcda6a5d54ba6df13371c2e2231bf889815c01c Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Fri, 11 Jul 2003 22:18:53 +0200 Subject: [PATCH 156/237] - fixed an error in the rpl_error_ignored_table test suite: the master port number can be different from 3306 when doing the release builds with Do-compile, therefore it has to be replaced with the correct value during the test run using the "--replace_result" function. --- mysql-test/r/rpl_error_ignored_table.result | 2 +- mysql-test/t/rpl_error_ignored_table.test | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/rpl_error_ignored_table.result b/mysql-test/r/rpl_error_ignored_table.result index 826e97a8004..e1486220542 100644 --- a/mysql-test/r/rpl_error_ignored_table.result +++ b/mysql-test/r/rpl_error_ignored_table.result @@ -9,7 +9,7 @@ insert into t1 values (1),(1); Duplicate entry '1' for key 1 show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 213 slave-relay-bin.002 254 master-bin.001 Yes Yes 0 0 213 254 +127.0.0.1 root MASTER_PORT 1 master-bin.001 213 slave-relay-bin.002 254 master-bin.001 Yes Yes 0 0 213 254 show tables like 't1'; Tables_in_test (t1) drop table t1; diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test index caa289a184d..686472433eb 100644 --- a/mysql-test/t/rpl_error_ignored_table.test +++ b/mysql-test/t/rpl_error_ignored_table.test @@ -12,6 +12,9 @@ save_master_pos; connection slave; # as the t1 table is ignored on the slave, the slave should be able to sync 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 show slave status; # check that the table has been ignored, because otherwise the test is nonsense show tables like 't1'; From 34c89189151f5dd6ba909c23c0eee53c26e30394 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 12 Jul 2003 15:06:40 +0200 Subject: [PATCH 157/237] removed 2 small useless if(). --- sql/log.cc | 9 ++++++++- sql/mysqld.cc | 11 +++-------- sql/sql_class.h | 1 - 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 7b35433b830..912cdf0a1a8 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1089,7 +1089,14 @@ bool MYSQL_LOG::write(Log_event* event_info) #endif if ((thd && !(thd->options & OPTION_BIN_LOG) && (thd->master_access & SUPER_ACL)) || - (local_db && !db_ok(local_db, binlog_do_db, binlog_ignore_db))) + (local_db && !db_ok(local_db, binlog_do_db, binlog_ignore_db)) + /* + This is the place for future tests like "do the involved tables match + (to be implemented) binlog_[wild_]{do|ignore}_table?" (WL#1049): + we will add a + && ... to the if(). + */ + ) { VOID(pthread_mutex_unlock(&LOCK_log)); DBUG_PRINT("error",("!db_ok")); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c21d71466ba..88ae612950e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1966,14 +1966,9 @@ bool open_log(MYSQL_LOG *log, const char *hostname, if (type == LOG_BIN) { char *p = fn_ext(opt_name); - if (p) - { - uint length=(uint) (p-opt_name); - strmake(tmp,opt_name,min(length,FN_REFLEN)); - opt_name=tmp; - } - if (*fn_ext(opt_name)) - log->set_no_rotate(1); + uint length=(uint) (p-opt_name); + strmake(tmp,opt_name,min(length,FN_REFLEN)); + opt_name=tmp; } return log->open(opt_name, type, 0, index_file_name, (read_append) ? SEQ_READ_APPEND : WRITE_CACHE, diff --git a/sql/sql_class.h b/sql/sql_class.h index cd622520df3..dfdcbcc996c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -175,7 +175,6 @@ public: inline void unlock_index() { pthread_mutex_unlock(&LOCK_index);} inline IO_CACHE *get_index_file() { return &index_file;} inline uint32 get_open_count() { return open_count; } - inline void set_no_rotate(bool no_rotate_arg) {no_rotate= no_rotate_arg;} }; /* character conversion tables */ From b7e1fe5ad1707a012ed50483cda5989c140ae920 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 12 Jul 2003 15:48:26 +0200 Subject: [PATCH 158/237] Member no_rotate in MYSQL_LOG was always 0, I delete it. --- sql/log.cc | 73 +++++++++++++++++++++---------------------------- sql/sql_class.h | 2 -- 2 files changed, 31 insertions(+), 44 deletions(-) diff --git a/sql/log.cc b/sql/log.cc index 912cdf0a1a8..96e1f1a2e01 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -83,7 +83,7 @@ static int find_uniq_filename(char *name) MYSQL_LOG::MYSQL_LOG() :bytes_written(0), last_time(0), query_start(0), name(0), file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), - no_rotate(0), need_start_event(1) + need_start_event(1) { /* We don't want to initialize LOCK_Log here as such initialization depends on @@ -721,7 +721,6 @@ err: RETURN VALUES 0 ok - LOG_INFO_PURGE_NO_ROTATE Binary file that can't be rotated LOG_INFO_EOF to_log not found */ @@ -731,9 +730,6 @@ int MYSQL_LOG::purge_logs(THD* thd, const char* to_log) LOG_INFO log_info; DBUG_ENTER("purge_logs"); - if (no_rotate) - DBUG_RETURN(LOG_INFO_PURGE_NO_ROTATE); - pthread_mutex_lock(&LOCK_index); if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/))) goto err; @@ -840,49 +836,42 @@ void MYSQL_LOG::new_file(bool need_lock) new_name_ptr= name; /* - Only rotate open logs that are marked non-rotatable - (binlog with constant name are non-rotatable) + If user hasn't specified an extension, generate a new log name + We have to do this here and not in open as we want to store the + new file name in the current binary log file. */ - if (!no_rotate) + if (generate_new_name(new_name, name)) + goto end; + new_name_ptr=new_name; + + if (log_type == LOG_BIN) { - /* - If user hasn't specified an extension, generate a new log name - We have to do this here and not in open as we want to store the - new file name in the current binary log file. - */ - if (generate_new_name(new_name, name)) - goto end; - new_name_ptr=new_name; - - if (log_type == LOG_BIN) + if (!no_auto_events) { - if (!no_auto_events) - { - /* - We log the whole file name for log file as the user may decide - to change base names at some point. - */ - THD* thd = current_thd; - Rotate_log_event r(thd,new_name+dirname_length(new_name)); - r.set_log_pos(this); - - /* - Because this log rotation could have been initiated by a master of - the slave running with log-bin, we set the flag on rotate - event to prevent infinite log rotation loop - */ - if (thd->slave_thread) - r.flags|= LOG_EVENT_FORCED_ROTATE_F; - r.write(&log_file); - bytes_written += r.get_event_len(); - } /* - Update needs to be signalled even if there is no rotate event - log rotation should give the waiting thread a signal to - discover EOF and move on to the next log. + We log the whole file name for log file as the user may decide + to change base names at some point. */ - signal_update(); + THD* thd = current_thd; + Rotate_log_event r(thd,new_name+dirname_length(new_name)); + r.set_log_pos(this); + + /* + Because this log rotation could have been initiated by a master of + the slave running with log-bin, we set the flag on rotate + event to prevent infinite log rotation loop + */ + if (thd->slave_thread) + r.flags|= LOG_EVENT_FORCED_ROTATE_F; + r.write(&log_file); + bytes_written += r.get_event_len(); } + /* + Update needs to be signalled even if there is no rotate event + log rotation should give the waiting thread a signal to + discover EOF and move on to the next log. + */ + signal_update(); } old_name=name; save_log_type=log_type; diff --git a/sql/sql_class.h b/sql/sql_class.h index dfdcbcc996c..24bbf9a6796 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -39,7 +39,6 @@ enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, #define LOG_INFO_IO -2 #define LOG_INFO_INVALID -3 #define LOG_INFO_SEEK -4 -#define LOG_INFO_PURGE_NO_ROTATE -5 #define LOG_INFO_MEM -6 #define LOG_INFO_FATAL -7 #define LOG_INFO_IN_USE -8 @@ -86,7 +85,6 @@ class MYSQL_LOG { volatile enum_log_type log_type; enum cache_type io_cache_type; bool write_error; - bool no_rotate; bool need_start_event; bool no_auto_events; // for relay binlog /* From 3c4b68eb1c381209acdc6bed9c38194a125a022b Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 12 Jul 2003 16:04:42 +0200 Subject: [PATCH 159/237] Cleaning after removing LOG_INFO_PURGE_NO_ROTATE. --- sql/sql_repl.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index a671facdc08..6f0ee69413d 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -282,8 +282,6 @@ int purge_master_logs(THD* thd, const char* to_log) case LOG_INFO_INVALID: errmsg = "Server configuration does not permit \ binlog purge"; break; case LOG_INFO_SEEK: errmsg = "Failed on fseek()"; break; - case LOG_INFO_PURGE_NO_ROTATE: errmsg = "Cannot purge unrotatable log"; - break; case LOG_INFO_MEM: errmsg = "Out of memory"; break; case LOG_INFO_FATAL: errmsg = "Fatal error during purge"; break; case LOG_INFO_IN_USE: errmsg = "A purgeable log is in use, will not purge"; From bc8d48920ed1b960a0fde17172a013101e73a2c4 Mon Sep 17 00:00:00 2001 From: "paul@ice.local" <> Date: Sat, 12 Jul 2003 11:45:43 -0500 Subject: [PATCH 160/237] perror.c: fix typo. --- BitKeeper/etc/logging_ok | 1 + extra/perror.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index be9d7b77650..b70b0a7b381 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -71,6 +71,7 @@ mysqldev@build.mysql2.com nick@mysql.com nick@nick.leippe.com paul@central.snake.net +paul@ice.local paul@teton.kitebird.com pem@mysql.com peter@linux.local diff --git a/extra/perror.c b/extra/perror.c index a2951bff66a..ca6bbfb54f9 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -111,7 +111,7 @@ static void usage(void) { print_version(); puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n"); - printf("Print a description for a system error code or a error code from\na MyISAM/ISAM/BDB table handler.\n"); + printf("Print a description for a system error code or an error code from\na MyISAM/ISAM/BDB table handler.\n"); printf("If you want to get the error for a negative error code, you should use\n-- before the first error code to tell perror that there was no more options.\n\n"); printf("Usage: %s [OPTIONS] [ERRORCODE [ERRORCODE...]]\n",my_progname); my_print_help(my_long_options); From 2340cff77aed26fe4ce129bd06dba2df38c53bd4 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sun, 13 Jul 2003 00:17:02 +0300 Subject: [PATCH 161/237] srv0start.c, srv0srv.h, os0file.h, os0file.c: Allow also O_DIRECT as innodb_flush_method; it only affects writing to data files --- innobase/include/os0file.h | 6 +- innobase/include/srv0srv.h | 1 + innobase/os/os0file.c | 117 +++++++++++++++++++++++++++---------- innobase/srv/srv0start.c | 4 ++ 4 files changed, 96 insertions(+), 32 deletions(-) diff --git a/innobase/include/os0file.h b/innobase/include/os0file.h index 1ec8b71d069..5c52f0e92bf 100644 --- a/innobase/include/os0file.h +++ b/innobase/include/os0file.h @@ -175,7 +175,11 @@ os_file_create( file is created (if exists, error), OS_FILE_OVERWRITE if a new file is created or an old overwritten */ ulint purpose,/* in: OS_FILE_AIO, if asynchronous, non-buffered i/o - is desired, OS_FILE_NORMAL, if any normal file */ + 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 */ /*************************************************************************** diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h index 1e54d7bfc35..f4255fc9a98 100644 --- a/innobase/include/srv0srv.h +++ b/innobase/include/srv0srv.h @@ -168,6 +168,7 @@ what these mean */ #define SRV_UNIX_O_DSYNC 2 #define SRV_UNIX_LITTLESYNC 3 #define SRV_UNIX_NOSYNC 4 +#define SRV_UNIX_O_DIRECT 5 /* Alternatives for file i/o in Windows */ #define SRV_WIN_IO_NORMAL 1 diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 612bd534fd1..a9a64ae7864 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -211,9 +211,9 @@ os_file_get_last_error(void) if (err != ERROR_DISK_FULL && err != ERROR_FILE_EXISTS) { ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB: Operating system error number %li in a file operation.\n" + " InnoDB: Operating system error number %lu in a file operation.\n" "InnoDB: See http://www.innodb.com/ibman.html for installation help.\n", - (long) err); + err); if (err == ERROR_PATH_NOT_FOUND) { fprintf(stderr, @@ -255,9 +255,9 @@ os_file_get_last_error(void) ut_print_timestamp(stderr); fprintf(stderr, - " InnoDB: Operating system error number %li in a file operation.\n" + " InnoDB: Operating system error number %lu in a file operation.\n" "InnoDB: See http://www.innodb.com/ibman.html for installation help.\n", - (long) err); + err); if (err == ENOENT) { fprintf(stderr, @@ -351,7 +351,8 @@ os_file_handle_error( fprintf(stderr, "InnoDB: File name %s\n", name); } - fprintf(stderr, "InnoDB: System call %s.\n", operation); + fprintf(stderr, "InnoDB: File operation call: '%s'.\n", + operation); fprintf(stderr, "InnoDB: Cannot continue operation.\n"); fflush(stderr); @@ -599,7 +600,11 @@ os_file_create( file is created (if exists, error), OS_FILE_OVERWRITE if a new is created or an old overwritten */ ulint purpose,/* in: OS_FILE_AIO, if asynchronous, non-buffered i/o - is desired, OS_FILE_NORMAL, if any normal file */ + 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 */ { @@ -624,8 +629,8 @@ try_again: } if (purpose == OS_FILE_AIO) { - /* use asynchronous (overlapped) io and no buffering - of writes in the OS */ + /* If specified, use asynchronous (overlapped) io and no + buffering of writes in the OS */ attributes = 0; #ifdef WIN_ASYNC_IO if (os_aio_use_native_aio) { @@ -633,17 +638,13 @@ try_again: } #endif #ifdef UNIV_NON_BUFFERED_IO - if (type == OS_LOG_FILE) { + if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) { /* Do not use unbuffered i/o to log files because - to allow group commit to work when MySQL binlogging - is used we must separate log file write and log - file flush to disk. */ - } else { - if (srv_win_file_flush_method == - SRV_WIN_IO_UNBUFFERED) { - attributes = attributes - | FILE_FLAG_NO_BUFFERING; - } + value 2 denotes that we do not flush the log at every + commit, but only once per second */ + } else if (srv_win_file_flush_method == + SRV_WIN_IO_UNBUFFERED) { + attributes = attributes | FILE_FLAG_NO_BUFFERING; } #endif } else if (purpose == OS_FILE_NORMAL) { @@ -653,12 +654,9 @@ try_again: /* Do not use unbuffered i/o to log files because value 2 denotes that we do not flush the log at every commit, but only once per second */ - } else { - if (srv_win_file_flush_method == - SRV_WIN_IO_UNBUFFERED) { - attributes = attributes - | FILE_FLAG_NO_BUFFERING; - } + } else if (srv_win_file_flush_method == + SRV_WIN_IO_UNBUFFERED) { + attributes = attributes | FILE_FLAG_NO_BUFFERING; } #endif } else { @@ -700,29 +698,69 @@ try_again: os_file_t file; int create_flag; ibool retry; + const char* mode_str = NULL; + const char* type_str = NULL; + const char* purpose_str = NULL; try_again: ut_a(name); if (create_mode == OS_FILE_OPEN) { + mode_str = "OPEN"; + create_flag = O_RDWR; } else if (create_mode == OS_FILE_CREATE) { + mode_str = "CREATE"; + create_flag = O_RDWR | O_CREAT | O_EXCL; } else if (create_mode == OS_FILE_OVERWRITE) { + mode_str = "OVERWRITE"; + create_flag = O_RDWR | O_CREAT | O_TRUNC; } else { create_flag = 0; ut_error; } - UT_NOT_USED(purpose); + if (type == OS_LOG_FILE) { + type_str = "LOG"; + } else if (type == OS_DATA_FILE) { + type_str = "DATA"; + } else { + ut_a(0); + } + + if (purpose == OS_FILE_AIO) { + purpose_str = "AIO"; + } else if (purpose == OS_FILE_NORMAL) { + purpose_str = "NORMAL"; + } else { + ut_a(0); + } +/* printf("Opening file %s, mode %s, type %s, purpose %s\n", + name, mode_str, type_str, purpose_str); */ #ifdef O_SYNC - if ((!srv_use_doublewrite_buf || type != OS_DATA_FILE) + /* We let O_SYNC only affect log files; note that we map O_DSYNC to + O_SYNC because the datasync options seemed to corrupt files in 2001 + in both Linux and Solaris */ + if (type == OS_LOG_FILE && srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) { +/* printf("Using O_SYNC for file %s\n", name); */ + create_flag = create_flag | O_SYNC; } +#endif +#ifdef O_DIRECT + /* We let O_DIRECT only affect data files */ + if (type != OS_LOG_FILE + && srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) { + +/* printf("Using O_DIRECT for file %s\n", name); */ + + create_flag = create_flag | O_DIRECT; + } #endif if (create_mode == OS_FILE_CREATE) { file = open(name, create_flag, os_innodb_umask); @@ -1319,6 +1357,7 @@ os_file_write( DWORD high; ulint i; ulint n_retries = 0; + ulint err; ut_a((offset & 0xFFFFFFFF) == offset); @@ -1386,18 +1425,27 @@ retry: if (!os_has_said_disk_full) { + err = (ulint)GetLastError(); + ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Error: Write to file %s failed at offset %lu %lu.\n" "InnoDB: %lu bytes should have been written, only %lu were written.\n" "InnoDB: Operating system error number %lu.\n" -"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n" -"InnoDB: what the error number means.\n" "InnoDB: Check that your OS and file system support files of this size.\n" "InnoDB: Check also that the disk is not full or a disk quota exceeded.\n", name, offset_high, offset, n, (ulint)len, - (ulint)GetLastError()); + err); + + if (strerror((int)err) != NULL) { + fprintf(stderr, +"InnoDB: Error number %lu means '%s'.\n", err, strerror((int)err)); + } + + fprintf(stderr, +"InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html\n" +"InnoDB: about operating system error numbers.\n"); os_has_said_disk_full = TRUE; } @@ -1421,12 +1469,19 @@ retry: " InnoDB: Error: Write to file %s failed at offset %lu %lu.\n" "InnoDB: %lu bytes should have been written, only %ld were written.\n" "InnoDB: Operating system error number %lu.\n" -"InnoDB: Look from section 13.2 at http://www.innodb.com/ibman.html\n" -"InnoDB: what the error number means or use the perror program of MySQL.\n" "InnoDB: Check that your OS and file system support files of this size.\n" "InnoDB: Check also that the disk is not full or a disk quota exceeded.\n", name, offset_high, offset, n, (long int)ret, (ulint)errno); + if (strerror(errno) != NULL) { + fprintf(stderr, +"InnoDB: Error number %lu means '%s'.\n", (ulint)errno, strerror(errno)); + } + + fprintf(stderr, +"InnoDB: See also section 13.2 at http://www.innodb.com/ibman.html\n" +"InnoDB: about operating system error numbers.\n"); + os_has_said_disk_full = TRUE; } diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 964e728b23c..a85c3615c1b 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1055,6 +1055,10 @@ innobase_start_or_create_for_mysql(void) (char*)"O_DSYNC")) { srv_unix_file_flush_method = SRV_UNIX_O_DSYNC; + } else if (0 == ut_strcmp(srv_file_flush_method_str, + (char*)"O_DIRECT")) { + srv_unix_file_flush_method = SRV_UNIX_O_DIRECT; + } else if (0 == ut_strcmp(srv_file_flush_method_str, (char*)"littlesync")) { srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC; From b46400b23e31f911e864fab534a1b2ea6b5d6c5f Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sun, 13 Jul 2003 17:18:06 +0300 Subject: [PATCH 162/237] srv0srv.c: Fix a benign bug introduced in 4.0.14: InnoDB could complain 'Error: trying to declare trx to enter InnoDB' if several threads tried to init the auto-inc counter for the same table at the same time; in theory, the bug could even lead to a hang of the server, but that shuld be extremely improbable --- innobase/srv/srv0srv.c | 45 +++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index a2314cde2dd..66819a747dc 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -1739,7 +1739,6 @@ srv_conc_enter_innodb( trx_t* trx) /* in: transaction object associated with the thread */ { - ibool has_slept = FALSE; srv_conc_slot_t* slot; ulint i; char err_buf[1000]; @@ -1758,7 +1757,7 @@ srv_conc_enter_innodb( return; } -retry: + os_fast_mutex_lock(&srv_conc_mutex); if (trx->declared_to_be_inside_innodb) { @@ -1769,6 +1768,9 @@ retry: fprintf(stderr, " InnoDB: Error: trying to declare trx to enter InnoDB, but\n" "InnoDB: it already is declared.\n%s\n", err_buf); + os_fast_mutex_unlock(&srv_conc_mutex); + + return; } if (srv_conc_n_threads < (lint)srv_thread_concurrency) { @@ -1782,22 +1784,6 @@ retry: return; } - /* If the transaction is not holding resources, let it sleep - for 100 milliseconds, and try again then */ - - if (!has_slept && !trx->has_search_latch - && NULL == UT_LIST_GET_FIRST(trx->trx_locks)) { - - has_slept = TRUE; /* We let is sleep only once to avoid - starvation */ - - os_fast_mutex_unlock(&srv_conc_mutex); - - os_thread_sleep(100000); - - goto retry; - } - /* Too many threads inside: put the current thread to a queue */ for (i = 0; i < OS_THREAD_MAX_N; i++) { @@ -2110,7 +2096,8 @@ srv_suspend_mysql_thread( os_event_t event; double wait_time; trx_t* trx; - ibool had_dict_lock = FALSE; + ibool had_dict_lock = FALSE; + ibool was_declared_inside_innodb = FALSE; ut_ad(!mutex_own(&kernel_mutex)); @@ -2158,11 +2145,16 @@ srv_suspend_mysql_thread( mutex_exit(&kernel_mutex); - /* We must declare this OS thread to exit InnoDB, since a possible - other thread holding a lock which this thread waits for must be - allowed to enter, sooner or later */ + if (trx->declared_to_be_inside_innodb) { + + was_declared_inside_innodb = TRUE; - srv_conc_force_exit_innodb(thr_get_trx(thr)); + /* We must declare this OS thread to exit InnoDB, since a + possible other thread holding a lock which this thread waits + for must be allowed to enter, sooner or later */ + + srv_conc_force_exit_innodb(trx); + } /* Release possible foreign key check latch */ if (trx->dict_operation_lock_mode == RW_S_LATCH) { @@ -2183,9 +2175,12 @@ srv_suspend_mysql_thread( row_mysql_freeze_data_dictionary(trx); } - /* Return back inside InnoDB */ + if (was_declared_inside_innodb) { + + /* Return back inside InnoDB */ - srv_conc_force_enter_innodb(thr_get_trx(thr)); + srv_conc_force_enter_innodb(trx); + } mutex_enter(&kernel_mutex); From 38595b1f28bab22dc93bb01cd8f8db857cd988e1 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Sun, 13 Jul 2003 18:50:43 +0300 Subject: [PATCH 163/237] srv0srv.c: Put back a 50 millisecond sleep in too high concurrency situations which I removed in the previous push; count also such sleeping threads to the InnoDB queue in SHOW INNODB STATUS --- innobase/srv/srv0srv.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 66819a747dc..f81b2d0a60e 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -1739,6 +1739,7 @@ srv_conc_enter_innodb( trx_t* trx) /* in: transaction object associated with the thread */ { + ibool has_slept = FALSE; srv_conc_slot_t* slot; ulint i; char err_buf[1000]; @@ -1759,7 +1760,7 @@ srv_conc_enter_innodb( } os_fast_mutex_lock(&srv_conc_mutex); - +retry: if (trx->declared_to_be_inside_innodb) { ut_print_timestamp(stderr); @@ -1784,6 +1785,28 @@ srv_conc_enter_innodb( return; } + /* If the transaction is not holding resources, let it sleep for 50 + milliseconds, and try again then */ + + if (!has_slept && !trx->has_search_latch + && NULL == UT_LIST_GET_FIRST(trx->trx_locks)) { + + has_slept = TRUE; /* We let is sleep only once to avoid + starvation */ + + srv_conc_n_waiting_threads++; + + os_fast_mutex_unlock(&srv_conc_mutex); + + os_thread_sleep(50000); + + os_fast_mutex_lock(&srv_conc_mutex); + + srv_conc_n_waiting_threads--; + + goto retry; + } + /* Too many threads inside: put the current thread to a queue */ for (i = 0; i < OS_THREAD_MAX_N; i++) { From ea5abe716020dd061db842fee106cfb520b36aa7 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Mon, 14 Jul 2003 05:54:08 +0300 Subject: [PATCH 164/237] Fixed wrong getopt table which caused core dumps --- sql/gen_lex_hash.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 1c6f124aac7..5b56d59f673 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -89,6 +89,7 @@ static struct my_option my_long_options[] = 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; struct hash_lex_struct From e1aa90a9bfed442c634685280330ed5e0aed0604 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Mon, 14 Jul 2003 10:12:05 +0300 Subject: [PATCH 165/237] Safety and speedup fixes: Changed is_open() to work as before. Added back inited argument to LOG --- mysql-test/r/rpl_flush_log_loop.result | 2 +- sql/handler.cc | 4 +- sql/item_func.cc | 2 +- sql/log.cc | 77 ++++++++++++-------------- sql/log_event.cc | 10 ++-- sql/repl_failsafe.cc | 2 +- sql/sql_base.cc | 2 +- sql/sql_class.h | 14 ++--- sql/sql_db.cc | 4 +- sql/sql_delete.cc | 6 +- sql/sql_insert.cc | 8 +-- sql/sql_load.cc | 8 +-- sql/sql_parse.cc | 4 +- sql/sql_rename.cc | 2 +- sql/sql_repl.cc | 12 ++-- sql/sql_table.cc | 10 ++-- sql/sql_update.cc | 4 +- 17 files changed, 80 insertions(+), 91 deletions(-) diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flush_log_loop.result index 3273ce43a17..18786b1931b 100644 --- a/mysql-test/r/rpl_flush_log_loop.result +++ b/mysql-test/r/rpl_flush_log_loop.result @@ -14,4 +14,4 @@ slave start; flush logs; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root SLAVE_PORT 60 slave-bin.001 79 relay-log.002 119 slave-bin.001 Yes Yes 0 0 79 119 +127.0.0.1 root SLAVE_PORT 60 slave-bin.001 79 relay-log.002 4 slave-bin.001 Yes Yes 0 0 79 4 diff --git a/sql/handler.cc b/sql/handler.cc index 0c95dbc4b31..4ea5bc0e9f5 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -346,7 +346,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) bool transaction_commited= 0; /* Update the binary log if we have cached some queries */ - if (trans == &thd->transaction.all && mysql_bin_log.is_open(1) && + if (trans == &thd->transaction.all && mysql_bin_log.is_open() && my_b_tell(&thd->transaction.trans_log)) { mysql_bin_log.write(thd, &thd->transaction.trans_log); @@ -385,7 +385,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) if (transaction_commited && thd->transaction.changed_tables) query_cache.invalidate(thd->transaction.changed_tables); #endif /*HAVE_QUERY_CACHE*/ - if (error && trans == &thd->transaction.all && mysql_bin_log.is_open(1)) + if (error && trans == &thd->transaction.all && mysql_bin_log.is_open()) sql_print_error("Error: Got error during commit; Binlog is not up to date!"); thd->variables.tx_isolation=thd->session_tx_isolation; if (operation_done) diff --git a/sql/item_func.cc b/sql/item_func.cc index f7b47736f33..8e9677cc459 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1504,7 +1504,7 @@ void item_user_lock_free(void) void item_user_lock_release(ULL *ull) { ull->locked=0; - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { char buf[256]; String tmp(buf,sizeof(buf)); diff --git a/sql/log.cc b/sql/log.cc index 96e1f1a2e01..1960c7d7cde 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -82,14 +82,14 @@ static int find_uniq_filename(char *name) MYSQL_LOG::MYSQL_LOG() :bytes_written(0), last_time(0), query_start(0), name(0), - file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), + file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0), need_start_event(1) { /* We don't want to initialize LOCK_Log here as such initialization depends on safe_mutex (when using safe_mutex) which depends on MY_INIT(), which is - called only in main(). Doing initialization here would make it happen before - main(). + called only in main(). Doing initialization here would make it happen + before main(). */ index_file_name[0] = 0; bzero((char*) &log_file,sizeof(log_file)); @@ -102,35 +102,20 @@ MYSQL_LOG::~MYSQL_LOG() cleanup(); } -void MYSQL_LOG::cleanup() /* this is called only once */ +/* this is called only once */ + +void MYSQL_LOG::cleanup() { - close(1); - (void) pthread_mutex_destroy(&LOCK_log); - (void) pthread_mutex_destroy(&LOCK_index); - (void) pthread_cond_destroy(&update_cond); + if (inited) + { + inited= 0; + close(1); + (void) pthread_mutex_destroy(&LOCK_log); + (void) pthread_mutex_destroy(&LOCK_index); + (void) pthread_cond_destroy(&update_cond); + } } -bool MYSQL_LOG::is_open(bool need_mutex) -{ - /* - Since MySQL 4.0.14, LOCK_log is always inited: - * for log/update_log/slow_log/bin_log which are global objects, this is done in - main(), even if the server does not use these logs. - * for relay_log which belongs to rli which belongs to active_mi, this is - done in the constructor of rli. - In older versions, we were never 100% sure that LOCK_log was inited, which - was a problem. - */ - if (need_mutex) - { - pthread_mutex_lock(&LOCK_log); - bool res= (log_type != LOG_CLOSED); - pthread_mutex_unlock(&LOCK_log); - return res; - } - else - return (log_type != LOG_CLOSED); -} int MYSQL_LOG::generate_new_name(char *new_name, const char *log_name) { @@ -164,13 +149,17 @@ void MYSQL_LOG::init(enum_log_type log_type_arg, DBUG_VOID_RETURN; } + void MYSQL_LOG::init_pthread_objects() { + DBUG_ASSERT(inited == 0); + inited= 1; (void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW); (void) pthread_cond_init(&update_cond, 0); } + /* Open a (new) log file. @@ -647,7 +636,7 @@ int MYSQL_LOG::purge_first_log(struct st_relay_log_info* rli) Assume that we have previously read the first log and stored it in rli->relay_log_name */ - DBUG_ASSERT(is_open(1)); + DBUG_ASSERT(is_open()); DBUG_ASSERT(rli->slave_running == 1); DBUG_ASSERT(!strcmp(rli->linfo.log_file_name,rli->relay_log_name)); DBUG_ASSERT(rli->linfo.index_file_offset == @@ -818,7 +807,7 @@ void MYSQL_LOG::new_file(bool need_lock) enum_log_type save_log_type; DBUG_ENTER("MYSQL_LOG::new_file"); - if (!is_open(need_lock)) + if (!is_open()) { DBUG_PRINT("info",("log is closed")); DBUG_VOID_RETURN; @@ -832,7 +821,7 @@ void MYSQL_LOG::new_file(bool need_lock) safe_mutex_assert_owner(&LOCK_log); safe_mutex_assert_owner(&LOCK_index); - // Reuse old name if not binlog and not update log + /* Reuse old name if not binlog and not update log */ new_name_ptr= name; /* @@ -971,11 +960,12 @@ err: bool MYSQL_LOG::write(THD *thd,enum enum_server_command command, const char *format,...) { - if (what_to_log & (1L << (uint) command)) + if (is_open() && (what_to_log & (1L << (uint) command))) { int error=0; VOID(pthread_mutex_lock(&LOCK_log)); + /* Test if someone closed between the is_open test and lock */ if (is_open()) { time_t skr; @@ -1076,16 +1066,14 @@ bool MYSQL_LOG::write(Log_event* event_info) #else IO_CACHE *file = &log_file; #endif + /* + In the future we need to add to the following if tests like + "do the involved tables match (to be implemented) + binlog_[wild_]{do|ignore}_table?" (WL#1049)" + */ if ((thd && !(thd->options & OPTION_BIN_LOG) && (thd->master_access & SUPER_ACL)) || - (local_db && !db_ok(local_db, binlog_do_db, binlog_ignore_db)) - /* - This is the place for future tests like "do the involved tables match - (to be implemented) binlog_[wild_]{do|ignore}_table?" (WL#1049): - we will add a - && ... to the if(). - */ - ) + (local_db && !db_ok(local_db, binlog_do_db, binlog_ignore_db))) { VOID(pthread_mutex_unlock(&LOCK_log)); DBUG_PRINT("error",("!db_ok")); @@ -1390,6 +1378,8 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, { bool error=0; time_t current_time; + if (!is_open()) + return 0; VOID(pthread_mutex_lock(&LOCK_log)); if (is_open()) { // Safety agains reopen @@ -1503,6 +1493,7 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, return error; } + /* Wait until we get a signal that the binary log has been updated @@ -1588,6 +1579,7 @@ void MYSQL_LOG::close(bool exiting) DBUG_VOID_RETURN; } + void MYSQL_LOG::set_max_size(ulong max_size_arg) { /* @@ -1605,6 +1597,7 @@ void MYSQL_LOG::set_max_size(ulong max_size_arg) DBUG_VOID_RETURN; } + /* Check if a string is a valid number diff --git a/sql/log_event.cc b/sql/log_event.cc index 5a0a243c57b..a6d2abbf894 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2167,7 +2167,7 @@ int Rand_log_event::exec_event(struct st_relay_log_info* rli) int Slave_log_event::exec_event(struct st_relay_log_info* rli) { - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) mysql_bin_log.write(this); return Log_event::exec_event(rli); } @@ -2217,7 +2217,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli) slave_print_error(rli,my_errno, "Write to '%s' failed", fname_buf); goto err; } - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) mysql_bin_log.write(this); error=0; // Everything is ok @@ -2237,7 +2237,7 @@ int Delete_file_log_event::exec_event(struct st_relay_log_info* rli) (void) my_delete(fname, MYF(MY_WME)); memcpy(p, ".info", 6); (void) my_delete(fname, MYF(MY_WME)); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) mysql_bin_log.write(this); return Log_event::exec_event(rli); } @@ -2260,7 +2260,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli) slave_print_error(rli,my_errno, "Write to '%s' failed", fname); goto err; } - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) mysql_bin_log.write(this); error=0; @@ -2319,7 +2319,7 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) (void) my_delete(fname, MYF(MY_WME)); memcpy(p, ".data", 6); (void) my_delete(fname, MYF(MY_WME)); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) mysql_bin_log.write(this); error = 0; diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 6f404d4b958..1552b3994e9 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -265,7 +265,7 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) LINT_INIT(cmp_res); DBUG_ENTER("translate_master"); - if (!mysql_bin_log.is_open(1)) + if (!mysql_bin_log.is_open()) { strmov(errmsg,"Binary log is not open"); DBUG_RETURN(1); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 217597ccda5..43718e5d93b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -574,7 +574,7 @@ void close_temporary_tables(THD *thd) next=table->next; close_temporary(table); } - if (query && found_user_tables && mysql_bin_log.is_open(1)) + if (query && found_user_tables && mysql_bin_log.is_open()) { /* The -1 is to remove last ',' */ Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0); diff --git a/sql/sql_class.h b/sql/sql_class.h index 24bbf9a6796..9908f034d7b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -58,13 +58,10 @@ typedef struct st_log_info class Log_event; -class MYSQL_LOG { +class MYSQL_LOG + { private: - /* - LOCK_log is inited by MYSQL_LOG::init(), so one should try to lock it only - if he is sure MYSQL_LOG::init() has been called (i.e. if 'inited' is true). - Same for LOCK_index. - */ + /* LOCK_log and LOCK_index are inited by init_pthread_objects() */ pthread_mutex_t LOCK_log, LOCK_index; pthread_cond_t update_cond; ulonglong bytes_written; @@ -84,7 +81,7 @@ class MYSQL_LOG { */ volatile enum_log_type log_type; enum cache_type io_cache_type; - bool write_error; + bool write_error, inited; bool need_start_event; bool no_auto_events; // for relay binlog /* @@ -162,8 +159,7 @@ public: int find_next_log(LOG_INFO* linfo, bool need_mutex); int get_current_log(LOG_INFO* linfo); uint next_file_id(); - bool is_open(bool need_mutex=0); - + inline bool is_open() { return log_type != LOG_CLOSED; } inline char* get_index_fname() { return index_file_name;} inline char* get_log_fname() { return log_file_name; } inline pthread_mutex_t* get_log_lock() { return &LOCK_log; } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 6045955334c..6251b1ec624 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -84,7 +84,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) } { mysql_update_log.write(thd,thd->query, thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); @@ -174,7 +174,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) thd->query= path; } mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 8b81e57d419..45acbaaa7ef 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -172,7 +172,7 @@ cleanup: if (deleted && (error <= 0 || !transactional_table)) { mysql_update_log.write(thd,thd->query, thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); @@ -476,7 +476,7 @@ bool multi_delete::send_eof() if (deleted && (error <= 0 || normal_tables)) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); @@ -588,7 +588,7 @@ end: if (!error) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, thd->tmp_table); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index f94963f2570..167ccf974c7 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -308,7 +308,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List &fields, if ((info.copied || info.deleted) && (error <= 0 || !transactional_table)) { mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); @@ -1143,7 +1143,7 @@ bool delayed_insert::handle_inserts(void) { int error; uint max_rows; - bool using_ignore=0, using_bin_log=mysql_bin_log.is_open(1); + bool using_ignore=0, using_bin_log=mysql_bin_log.is_open(); delayed_row *row; DBUG_ENTER("handle_inserts"); @@ -1361,7 +1361,7 @@ void select_insert::send_error(uint errcode,const char *err) if (last_insert_id) thd->insert_id(last_insert_id); // For binary log mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, table->file->has_transactions()); @@ -1387,7 +1387,7 @@ bool select_insert::send_eof() thd->insert_id(last_insert_id); // For binary log /* Write to binlog before commiting transaction */ mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, table->file->has_transactions()); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 7a20fbfd928..ee573672c35 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -219,7 +219,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, DBUG_RETURN(-1); // Can't allocate buffers } - if (!opt_old_rpl_compat && mysql_bin_log.is_open(1)) + if (!opt_old_rpl_compat && mysql_bin_log.is_open()) { lf_info.thd = thd; lf_info.ex = ex; @@ -281,7 +281,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, { if (transactional_table) ha_autocommit_or_rollback(thd,error); - if (!opt_old_rpl_compat && mysql_bin_log.is_open(1)) + if (!opt_old_rpl_compat && mysql_bin_log.is_open()) { if (lf_info.wrote_create_file) { @@ -315,7 +315,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, if (!log_delayed) thd->options|=OPTION_STATUS_NO_TRANS_UPDATE; - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { if (opt_old_rpl_compat) { @@ -607,7 +607,7 @@ READ_INFO::READ_INFO(File file_par, uint tot_length, String &field_term, cache.read_function = _my_b_net_read; need_end_io_cache = 1; - if (!opt_old_rpl_compat && mysql_bin_log.is_open(1)) + if (!opt_old_rpl_compat && mysql_bin_log.is_open()) cache.pre_read = cache.pre_close = (IO_CACHE_CALLBACK) log_loaded_block; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a32dce4d704..70c0f772d7d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2432,7 +2432,7 @@ mysql_execute_command(void) lex->sql_command == SQLCOM_REVOKE))) { mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); @@ -2452,7 +2452,7 @@ mysql_execute_command(void) if (!res) { mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index cfc6e5b0721..d7e998264f3 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -80,7 +80,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) if (!error) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 6f0ee69413d..13b22d6a221 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -269,7 +269,7 @@ int purge_master_logs(THD* thd, const char* to_log) const char* errmsg = 0; int res; - if (!mysql_bin_log.is_open(1)) + if (!mysql_bin_log.is_open()) goto end; mysql_bin_log.make_log_name(search_file_name, to_log); @@ -333,7 +333,7 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, } #endif - if (!mysql_bin_log.is_open(1)) + if (!mysql_bin_log.is_open()) { errmsg = "Binary log is not open"; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; @@ -970,7 +970,7 @@ int change_master(THD* thd, MASTER_INFO* mi) int reset_master(THD* thd) { - if (!mysql_bin_log.is_open(1)) + if (!mysql_bin_log.is_open()) { my_error(ER_FLUSH_MASTER_BINLOG_CLOSED, MYF(ME_BELL+ME_WAITTANG)); return 1; @@ -1008,7 +1008,7 @@ int show_binlog_events(THD* thd) if (send_fields(thd, field_list, 1)) DBUG_RETURN(-1); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { LEX_MASTER_INFO *lex_mi = &thd->lex.mi; ha_rows event_count, limit_start, limit_end; @@ -1108,7 +1108,7 @@ int show_binlog_info(THD* thd) String* packet = &thd->packet; packet->length(0); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { LOG_INFO li; mysql_bin_log.get_current_log(&li); @@ -1146,7 +1146,7 @@ int show_binlogs(THD* thd) String *packet = &thd->packet; uint length; - if (!mysql_bin_log.is_open(1)) + if (!mysql_bin_log.is_open()) { //TODO: Replace with ER() error message send_error(net, 0, "You are not using binary logging"); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2d024ded5db..cf430aec35d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -235,7 +235,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, if (!dont_log_query) { mysql_update_log.write(thd, thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, tmp_table_deleted && !some_tables_deleted); @@ -766,7 +766,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, { // Must be written before unlock mysql_update_log.write(thd,thd->query, thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, test(create_info->options & @@ -1548,7 +1548,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!error) { mysql_update_log.write(thd, thd->query, thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); @@ -1918,7 +1918,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } mysql_update_log.write(thd, thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); @@ -2050,7 +2050,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } thd->proc_info="end"; mysql_update_log.write(thd, thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, 0); mysql_bin_log.write(&qinfo); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 42ba00d3ad5..3179c8e0f24 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -317,7 +317,7 @@ int mysql_update(THD *thd, if (updated && (error <= 0 || !transactional_table)) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); @@ -933,7 +933,7 @@ bool multi_update::send_eof() if (updated && (local_error <= 0 || !trans_safe)) { mysql_update_log.write(thd,thd->query,thd->query_length); - if (mysql_bin_log.is_open(1)) + if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query, thd->query_length, log_delayed); From 8e23f54fec343e7dcfb20890d6c444ada96619de Mon Sep 17 00:00:00 2001 From: "ram@mysql.r18.ru" <> Date: Mon, 14 Jul 2003 12:39:10 +0500 Subject: [PATCH 166/237] backport fix for the bug #803: INTERVAL(NULL, ....) --- mysql-test/r/func_set.result | 2 +- sql/item_cmpfunc.cc | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result index dfd7750adaf..eeeb216d142 100644 --- a/mysql-test/r/func_set.result +++ b/mysql-test/r/func_set.result @@ -27,4 +27,4 @@ find_in_set("abc","abc") find_in_set("ab","abc") find_in_set("abcd","abc") 1 0 0 select interval(null, 1, 10, 100); interval(null, 1, 10, 100) -NULL +-1 diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 731f9b61438..8c58c58a67d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -311,7 +311,7 @@ void Item_func_interval::split_sum_func(List &fields) } /* - return NULL if null value, + return -1 if null value, 0 if lower than lowest 1 - arg_count if between args[n] and args[n+1] arg_count+1 if higher than biggest argument @@ -321,10 +321,7 @@ longlong Item_func_interval::val_int() { double value= item->val(); if (item->null_value) - { - null_value= 1; - return -1; - } + return -1; // -1 if NULL if (intervals) { // Use binary search to find interval uint start= 0, end= arg_count - 1; From 9b4ebf3d295ff7b8a3501ec113e3bdd67703fdb6 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Mon, 14 Jul 2003 12:40:58 +0500 Subject: [PATCH 167/237] Proposed bugfix for #712 Monty revoked any locks for temporary tables in ha_myisam::external_lock() But further code bans using write cache on nonlocked tables this makes operations much slower --- myisam/mi_locking.c | 8 ++++++++ myisam/myisamdef.h | 1 + sql/ha_myisam.cc | 9 +++++---- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c index cbde05d31f5..648c447ae30 100644 --- a/myisam/mi_locking.c +++ b/myisam/mi_locking.c @@ -39,6 +39,14 @@ int mi_lock_database(MI_INFO *info, int lock_type) if (share->options & HA_OPTION_READ_ONLY_DATA || info->lock_type == lock_type) DBUG_RETURN(0); + if (lock_type == MI_TEMPORARY_TABLE) + { + ++share->w_locks; + ++share->tot_locks; + info->lock_type= lock_type; + DBUG_RETURN(0); + } + flag=error=0; pthread_mutex_lock(&share->intern_lock); if (share->kfile >= 0) /* May only be false on windows */ diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 7631b245b9b..9c2f34990ed 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -101,6 +101,7 @@ typedef struct st_mi_state_info #define MI_COLUMNDEF_SIZE (2*3+1) #define MI_BASE_INFO_SIZE (5*8 + 8*4 + 4 + 4*2 + 16) #define MI_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */ +#define MI_TEMPORARY_TABLE ((1 & ~F_RDLCK) | (2 & ~F_WRLCK) | (4 & ~F_UNLCK)) typedef struct st_mi_base_info { diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 595123f7ac1..969fa3232c3 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -559,7 +559,8 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) strmov(fixed_name,file->filename); // Don't lock tables if we have used LOCK TABLE - if (!thd->locked_tables && mi_lock_database(file,F_WRLCK)) + if (!thd->locked_tables && + mi_lock_database(file, table->tmp_table ? MI_TEMPORARY_TABLE : F_WRLCK)) { mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno); DBUG_RETURN(HA_ADMIN_FAILED); @@ -999,9 +1000,9 @@ int ha_myisam::delete_table(const char *name) int ha_myisam::external_lock(THD *thd, int lock_type) { - if (!table->tmp_table) - return mi_lock_database(file,lock_type); - return 0; + return mi_lock_database(file, !table->tmp_table ? + lock_type : ((lock_type == F_UNLCK) ? + F_UNLCK : MI_TEMPORARY_TABLE)); } From df7c1e816515da233972508347ece5c75fd28de7 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Mon, 14 Jul 2003 14:59:26 +0300 Subject: [PATCH 168/237] Better fix for bug #791: At binlog rotation, INSERTs may not find their way into the binlog --- mysql-test/t/rpl_flush_log_loop.test | 1 + sql/log.cc | 30 +++++++++++++++------------- sql/mysqld.cc | 4 ++-- sql/slave.cc | 6 +++--- sql/sql_class.h | 12 +++++++---- 5 files changed, 30 insertions(+), 23 deletions(-) diff --git a/mysql-test/t/rpl_flush_log_loop.test b/mysql-test/t/rpl_flush_log_loop.test index c68fbb7111a..8a3da1a2b02 100644 --- a/mysql-test/t/rpl_flush_log_loop.test +++ b/mysql-test/t/rpl_flush_log_loop.test @@ -14,6 +14,7 @@ slave stop; eval change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=$SLAVE_MYPORT; slave start; +sleep 5; flush logs; sleep 5; --replace_result $SLAVE_MYPORT SLAVE_PORT diff --git a/sql/log.cc b/sql/log.cc index 1960c7d7cde..e4bdcf55534 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -109,7 +109,7 @@ void MYSQL_LOG::cleanup() if (inited) { inited= 0; - close(1); + close(LOG_CLOSE_INDEX); (void) pthread_mutex_destroy(&LOCK_log); (void) pthread_mutex_destroy(&LOCK_index); (void) pthread_cond_destroy(&update_cond); @@ -315,6 +315,7 @@ bool MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg, break; } case LOG_CLOSED: // Impossible + case LOG_TO_BE_OPENED: DBUG_ASSERT(1); break; } @@ -332,7 +333,7 @@ shutdown the MySQL server and restart it.", log_name, errno); end_io_cache(&log_file); end_io_cache(&index_file); safeFree(name); - log_type=LOG_CLOSED; + log_type= LOG_CLOSED; DBUG_RETURN(1); } @@ -565,7 +566,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) save_name=name; name=0; // Protect against free save_log_type=log_type; - close(0); // Don't close the index file + close(LOG_CLOSE_TO_BE_OPENED); /* First delete all old log files */ @@ -583,7 +584,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) } /* Start logging with a new file */ - close(1); // Close index file + close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); my_delete(index_file_name, MYF(MY_WME)); // Reset (open will update) if (!thd->slave_thread) need_start_event=1; @@ -865,7 +866,7 @@ void MYSQL_LOG::new_file(bool need_lock) old_name=name; save_log_type=log_type; name=0; // Don't free name - close(); + close(LOG_CLOSE_TO_BE_OPENED); /* Note that at this point, log_type == LOG_CLOSED (important for is_open()). @@ -1528,24 +1529,25 @@ void MYSQL_LOG:: wait_for_update(THD* thd) SYNOPSIS close() - exiting Set to 1 if we should also close the index file - This can be set to 0 if we are going to do call open - at once after close, in which case we don't want to - close the index file. - We only write a 'stop' event to the log if exiting is set + exiting Bitmask for one or more of the following bits: + LOG_CLOSE_INDEX if we should close the index file + LOG_CLOSE_TO_BE_OPENED if we intend to call open + at once after close. + LOG_CLOSE_STOP_EVENT write a 'stop' event to the log NOTES One can do an open on the object at once after doing a close. The internal structures are not freed until cleanup() is called */ -void MYSQL_LOG::close(bool exiting) +void MYSQL_LOG::close(uint exiting) { // One can't set log_type here! DBUG_ENTER("MYSQL_LOG::close"); DBUG_PRINT("enter",("exiting: %d", (int) exiting)); if (is_open()) { - if (log_type == LOG_BIN && !no_auto_events && exiting) + if (log_type == LOG_BIN && !no_auto_events && + (exiting & LOG_CLOSE_STOP_EVENT)) { Stop_log_event s; s.set_log_pos(this); @@ -1565,7 +1567,7 @@ void MYSQL_LOG::close(bool exiting) called a not complete close earlier and the index file is still open. */ - if (exiting && my_b_inited(&index_file)) + if ((exiting & LOG_CLOSE_INDEX) && my_b_inited(&index_file)) { end_io_cache(&index_file); if (my_close(index_file.file, MYF(0)) < 0 && ! write_error) @@ -1574,7 +1576,7 @@ void MYSQL_LOG::close(bool exiting) sql_print_error(ER(ER_ERROR_ON_WRITE), index_file_name, errno); } } - log_type= LOG_CLOSED; + log_type= (exiting & LOG_CLOSE_TO_BE_OPENED) ? LOG_TO_BE_OPENED : LOG_CLOSED; safeFree(name); DBUG_VOID_RETURN; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 88ae612950e..9b8d12e845d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4210,8 +4210,8 @@ static void usage(void) puts("\ Copyright (C) 2000 MySQL AB, by Monty and others\n\ This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n\ -Starts the MySQL server\n"); +and you are welcome to modify and redistribute it under the GPL license\n\n\ +Starts the MySQL database server\n"); printf("Usage: %s [OPTIONS]\n", my_progname); #ifdef __WIN__ diff --git a/sql/slave.cc b/sql/slave.cc index 557e288539b..6ace446a341 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1314,7 +1314,7 @@ file '%s')", fname); if (info_fd >= 0) my_close(info_fd, MYF(0)); rli->info_fd= -1; - rli->relay_log.close(1); + rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); pthread_mutex_unlock(&rli->data_lock); DBUG_RETURN(1); } @@ -1374,7 +1374,7 @@ err: if (info_fd >= 0) my_close(info_fd, MYF(0)); rli->info_fd= -1; - rli->relay_log.close(1); + rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); pthread_mutex_unlock(&rli->data_lock); DBUG_RETURN(1); } @@ -2989,7 +2989,7 @@ void end_relay_log_info(RELAY_LOG_INFO* rli) rli->cur_log_fd = -1; } rli->inited = 0; - rli->relay_log.close(1); + rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); DBUG_VOID_RETURN; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 9908f034d7b..dcc839e13b1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -30,11 +30,11 @@ class Slave_log_event; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY }; enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE }; -enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN }; +enum enum_log_type { LOG_CLOSED, LOG_TO_BE_OPENED, LOG_NORMAL, LOG_NEW, LOG_BIN}; enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, DELAY_KEY_WRITE_ALL }; -// log info errors +/* log info errors */ #define LOG_INFO_EOF -1 #define LOG_INFO_IO -2 #define LOG_INFO_INVALID -3 @@ -43,6 +43,11 @@ enum enum_delay_key_write { DELAY_KEY_WRITE_NONE, DELAY_KEY_WRITE_ON, #define LOG_INFO_FATAL -7 #define LOG_INFO_IN_USE -8 +/* bitmap to SQL_LOG::close() */ +#define LOG_CLOSE_INDEX 1 +#define LOG_CLOSE_TO_BE_OPENED 2 +#define LOG_CLOSE_STOP_EVENT 4 + struct st_relay_log_info; typedef struct st_log_info @@ -150,8 +155,7 @@ public: int purge_logs(THD* thd, const char* to_log); int purge_first_log(struct st_relay_log_info* rli); bool reset_logs(THD* thd); - // if we are exiting, we also want to close the index file - void close(bool exiting = 0); + void close(uint exiting); // iterating through the log index file int find_log_pos(LOG_INFO* linfo, const char* log_name, From 79f18d5bb9272f3cce3fb8477c8229d422219c36 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Mon, 14 Jul 2003 15:38:20 +0300 Subject: [PATCH 169/237] ha_innodb.h: Fix wrong error message: If one tried to create table with a very big row len, MySQL claimed the max len is 64 kB for InnoDB, while it normally is 8000 bytes --- sql/ha_innodb.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 86f409aff67..308deb68611 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -32,7 +32,6 @@ typedef struct st_innobase_share { uint table_name_length,use_count; } INNOBASE_SHARE; - /* The class defining a handle to an Innodb table */ class ha_innobase: public handler { @@ -112,7 +111,9 @@ class ha_innobase: public handler return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEY_READ_ONLY); } - uint max_record_length() const { return HA_MAX_REC_LENGTH; } + /* max_record_.. should be slightly less + than 1/2 UNIV_PAGE_SIZE */ + uint max_record_length() const { return 8000; } uint max_keys() const { return MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } /* An InnoDB page must store >= 2 keys; From cda64baab5de0402ef21e1cd8d063061bee175bf Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Mon, 14 Jul 2003 15:53:50 +0300 Subject: [PATCH 170/237] ha_innodb.h: Revert the previous patch: MySQL would not allow creation of VARCHAR columns whose total max length is > 8000 bytes, though InnoDB can easily store them as trailing spaces are removed --- sql/ha_innodb.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 308deb68611..8a51019b18e 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -111,9 +111,7 @@ class ha_innobase: public handler return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEY_READ_ONLY); } - /* max_record_.. should be slightly less - than 1/2 UNIV_PAGE_SIZE */ - uint max_record_length() const { return 8000; } + uint max_record_length() const { return HA_MAX_REC_LENGTH; } uint max_keys() const { return MAX_KEY; } uint max_key_parts() const { return MAX_REF_PARTS; } /* An InnoDB page must store >= 2 keys; From bf6938fd4d74346cb48247a694a6aea8a24a3cf8 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Mon, 14 Jul 2003 16:04:20 +0300 Subject: [PATCH 171/237] errmsg.txt: Correct a misleading error message about max row length --- sql/share/english/errmsg.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 3d7ca3b28df..0ce90ac0dab 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -119,7 +119,7 @@ "Unknown character set: '%-.64s'", "Too many tables. MySQL can only use %d tables in a join", "Too many columns", -"Too big row size. The maximum row size, not counting BLOBs, is %d. You have to change some fields to BLOBs", +"Too big row size. The maximum row size, not counting BLOBs, is %d (can be lower for some table types). You have to change some fields to BLOBs", "Thread stack overrun: Used: %ld of a %ld stack. Use 'mysqld -O thread_stack=#' to specify a bigger stack if needed", "Cross dependency found in OUTER JOIN. Examine your ON conditions", "Column '%-.64s' is used with UNIQUE or INDEX but is not defined as NOT NULL", From 00d2498a9e5dc041cc9e69e0c729df56583467d3 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Mon, 14 Jul 2003 22:02:26 +0200 Subject: [PATCH 172/237] Added missing --replace_result for ports in SHOW SLAVE STATUS. --- mysql-test/r/rpl_max_relay_size.result | 12 ++++++------ mysql-test/t/rpl_max_relay_size.test | 6 ++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result index 5c5a9d622e5..1fa3fcd1adb 100644 --- a/mysql-test/r/rpl_max_relay_size.result +++ b/mysql-test/r/rpl_max_relay_size.result @@ -16,7 +16,7 @@ select @@global.max_relay_log_size; start slave; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.014 1221 master-bin.001 Yes Yes 0 0 50477 1221 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.014 1221 master-bin.001 Yes Yes 0 0 50477 1221 stop slave; reset slave; set global max_relay_log_size=(5*4096); @@ -26,7 +26,7 @@ select @@global.max_relay_log_size; start slave; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 9457 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 9457 stop slave; reset slave; set global max_relay_log_size=0; @@ -36,25 +36,25 @@ select @@global.max_relay_log_size; start slave; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.008 1283 master-bin.001 Yes Yes 0 0 50477 1283 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.008 1283 master-bin.001 Yes Yes 0 0 50477 1283 stop slave; reset slave; flush logs; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 4 slave-relay-bin.001 4 No No 0 0 0 4 +127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4 reset slave; start slave; flush logs; create table t1 (a int); show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50535 slave-relay-bin.009 62 master-bin.001 Yes Yes 0 0 50535 62 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50535 slave-relay-bin.009 62 master-bin.001 Yes Yes 0 0 50535 62 flush logs; drop table t1; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50583 slave-relay-bin.010 52 master-bin.001 Yes Yes 0 0 50583 52 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50583 slave-relay-bin.010 52 master-bin.001 Yes Yes 0 0 50583 52 flush logs; show master status; File Position Binlog_do_db Binlog_ignore_db diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test index 4befe4024fc..7db1ffd7ae2 100644 --- a/mysql-test/t/rpl_max_relay_size.test +++ b/mysql-test/t/rpl_max_relay_size.test @@ -28,6 +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 show slave status; stop slave; reset slave; @@ -35,6 +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 show slave status; stop slave; reset slave; @@ -42,6 +44,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 show slave status; # Tests below are mainly to ensure that we have not coded with wrong assumptions @@ -51,6 +54,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 show slave status; reset slave; @@ -65,6 +69,7 @@ create table t1 (a int); save_master_pos; connection slave; sync_with_master; +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; # one more rotation, to be sure Relay_log_space is correctly updated flush logs; @@ -73,6 +78,7 @@ drop table t1; save_master_pos; connection slave; sync_with_master; +--replace_result $MASTER_MYPORT MASTER_PORT show slave status; connection master; From b1b73137de81f98f09726400adbc0633ce5f21f9 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Mon, 14 Jul 2003 23:49:19 +0300 Subject: [PATCH 173/237] Fixed wrong test in LOG::close Fixed test for binary build --- mysql-test/r/rpl_max_relay_size.result | 12 ++++++------ mysql-test/t/rpl_max_relay_size.test | 6 ++++++ sql/log.cc | 4 ++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result index 5c5a9d622e5..1fa3fcd1adb 100644 --- a/mysql-test/r/rpl_max_relay_size.result +++ b/mysql-test/r/rpl_max_relay_size.result @@ -16,7 +16,7 @@ select @@global.max_relay_log_size; start slave; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.014 1221 master-bin.001 Yes Yes 0 0 50477 1221 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.014 1221 master-bin.001 Yes Yes 0 0 50477 1221 stop slave; reset slave; set global max_relay_log_size=(5*4096); @@ -26,7 +26,7 @@ select @@global.max_relay_log_size; start slave; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 9457 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 9457 stop slave; reset slave; set global max_relay_log_size=0; @@ -36,25 +36,25 @@ select @@global.max_relay_log_size; start slave; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50477 slave-relay-bin.008 1283 master-bin.001 Yes Yes 0 0 50477 1283 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.008 1283 master-bin.001 Yes Yes 0 0 50477 1283 stop slave; reset slave; flush logs; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 4 slave-relay-bin.001 4 No No 0 0 0 4 +127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4 reset slave; start slave; flush logs; create table t1 (a int); show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50535 slave-relay-bin.009 62 master-bin.001 Yes Yes 0 0 50535 62 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50535 slave-relay-bin.009 62 master-bin.001 Yes Yes 0 0 50535 62 flush logs; drop table t1; show slave status; 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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root 9306 1 master-bin.001 50583 slave-relay-bin.010 52 master-bin.001 Yes Yes 0 0 50583 52 +127.0.0.1 root MASTER_PORT 1 master-bin.001 50583 slave-relay-bin.010 52 master-bin.001 Yes Yes 0 0 50583 52 flush logs; show master status; File Position Binlog_do_db Binlog_ignore_db diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test index 4befe4024fc..a2167b1ef36 100644 --- a/mysql-test/t/rpl_max_relay_size.test +++ b/mysql-test/t/rpl_max_relay_size.test @@ -28,6 +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 show slave status; stop slave; reset slave; @@ -35,6 +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 show slave status; stop slave; reset slave; @@ -42,6 +44,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 show slave status; # Tests below are mainly to ensure that we have not coded with wrong assumptions @@ -51,6 +54,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 show slave status; reset slave; @@ -65,6 +69,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 show slave status; # one more rotation, to be sure Relay_log_space is correctly updated flush logs; @@ -73,6 +78,7 @@ drop table t1; save_master_pos; connection slave; sync_with_master; +--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT show slave status; connection master; diff --git a/sql/log.cc b/sql/log.cc index e4bdcf55534..17715620950 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -584,7 +584,7 @@ bool MYSQL_LOG::reset_logs(THD* thd) } /* Start logging with a new file */ - close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT); + close(LOG_CLOSE_INDEX); my_delete(index_file_name, MYF(MY_WME)); // Reset (open will update) if (!thd->slave_thread) need_start_event=1; @@ -1544,7 +1544,7 @@ void MYSQL_LOG::close(uint exiting) { // One can't set log_type here! DBUG_ENTER("MYSQL_LOG::close"); DBUG_PRINT("enter",("exiting: %d", (int) exiting)); - if (is_open()) + if (log_type != LOG_CLOSED && log_type != LOG_TO_BE_OPENED) { if (log_type == LOG_BIN && !no_auto_events && (exiting & LOG_CLOSE_STOP_EVENT)) From 4542d142d780cb7e9a80398e0015d32638aaa7cd Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Tue, 15 Jul 2003 13:10:20 +0300 Subject: [PATCH 174/237] Portability fixes --- acinclude.m4 | 13 ++++++++++--- sql/item_strfunc.cc | 4 ++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index abeb2024f4a..f7d89ecf35a 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -126,12 +126,19 @@ AC_DEFUN(MYSQL_CHECK_ZLIB_WITH_COMPRESS, [ save_LIBS="$LIBS" LIBS="-l$1 $LIBS" AC_CACHE_CHECK([if libz with compress], mysql_cv_compress, -[AC_TRY_LINK([#include +[AC_TRY_RUN([#include #ifdef __cplusplus extern "C" #endif -], -[ return compress(0, (unsigned long*) 0, "", 0); +int main(int argv, char **argc) +{ + return 0; +} + +int link_test() +{ + return compress(0, (unsigned long*) 0, "", 0); +} ], mysql_cv_compress=yes, mysql_cv_compress=no)]) if test "$mysql_cv_compress" = "yes" then diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 801b77ffcce..8cc3d24f7d9 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1471,6 +1471,10 @@ String *Item_func_format::val_str(String *str) return 0; /* purecov: inspected */ dec= decimals ? decimals+1 : 0; str->set(nr,decimals); +#ifdef HAVE_ISNAN + if (isnan(nr)) + return str; +#endif str_length=str->length(); if (nr < 0) str_length--; // Don't count sign From ca8831e1ad37c4e5f6b3e183873b7a33b6726544 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Tue, 15 Jul 2003 12:50:17 +0200 Subject: [PATCH 175/237] - removed options sort_buffer and key_buffer from calls to (my)isamchk in mysqld_safe (commented out by default), to not override any options defined in my.cnf (thanks to Axel Schwenke from Jobpilot.de for the suggestion) --- scripts/mysqld_safe.sh | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index fcd8e26c901..d7e3eedb84e 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -274,12 +274,16 @@ then fi # -# Uncomment the following lines if you want all tables to be automaticly -# checked and repaired at start +# Uncomment the following lines if you want all tables to be automatically +# checked and repaired during startup. You should add sensible key_buffer +# and sort_buffer values to my.cnf to improve check performance or require +# less disk space. +# Alternatively, you can start mysqld with the "myisam-recover" option. See +# the manual for details. # # echo "Checking tables in $DATADIR" -# $MY_BASEDIR_VERSION/bin/myisamchk --silent --force --fast --medium-check -O key_buffer=64M -O sort_buffer=64M $DATADIR/*/*.MYI -# $MY_BASEDIR_VERSION/bin/isamchk --silent --force -O sort_buffer=64M $DATADIR/*/*.ISM +# $MY_BASEDIR_VERSION/bin/myisamchk --silent --force --fast --medium-check $DATADIR/*/*.MYI +# $MY_BASEDIR_VERSION/bin/isamchk --silent --force $DATADIR/*/*.ISM echo "Starting $MYSQLD daemon with databases from $DATADIR" From 25b16cd6ceca424e45f3c087493d505952ed63fa Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 15 Jul 2003 20:43:57 +0200 Subject: [PATCH 176/237] bug #702 - ALTER TABLE tm UNION=(t1,t2) doesn't work if t1.MYD is compressed --- myisammrg/myrg_open.c | 9 +++------ sql/handler.cc | 3 +++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c index 7ff00270c68..5188669cad1 100644 --- a/myisammrg/myrg_open.c +++ b/myisammrg/myrg_open.c @@ -33,7 +33,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) { int save_errno,i,errpos; - uint files,dir_length,length,options, key_parts; + uint files,dir_length,length,key_parts; ulonglong file_offset; char name_buff[FN_REFLEN*2],buff[FN_REFLEN],*end; MYRG_INFO info,*m_info; @@ -110,13 +110,11 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) } errpos=2; - options= (uint) ~0; for (i=files ; i-- > 0 ; ) { uint j; m_info->open_tables[i].table=isam; m_info->options|=isam->s->options; - options&=isam->s->options; m_info->records+=isam->state->records; m_info->del+=isam->state->del; m_info->data_file_length+=isam->state->data_file_length; @@ -125,9 +123,8 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking) if (i) isam=(MI_INFO*) (isam->open_list.next->data); } - /* Don't force readonly if not all tables are readonly */ - if (! (options & (HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA))) - m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); + /* Don't mark table readonly, for ALTER TABLE ... UNION=(...) to work */ + m_info->options&= ~(HA_OPTION_COMPRESS_RECORD | HA_OPTION_READ_ONLY_DATA); /* Fix fileinfo for easyer debugging (actually set by rrnd) */ file_offset=0; diff --git a/sql/handler.cc b/sql/handler.cc index 4ea5bc0e9f5..505f64dff43 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -801,6 +801,9 @@ void handler::print_error(int error, myf errflag) int textno=ER_GET_ERRNO; switch (error) { + case EACCES: + textno=ER_OPEN_AS_READONLY; + break; case EAGAIN: textno=ER_FILE_USED; break; From 42d6dea61b14a608e987d417e5a2d6f2a742187e Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 16 Jul 2003 12:06:55 +0200 Subject: [PATCH 177/237] - fixed the automatic generation of support-files/MacOSX/ReadMe.txt - a node name was changed in manual.texi which resulted in a very large ReadMe.txt file, as the generating script could not find the (renamed) ending node. Fixed the ending node name in Docs/Makefile.am and the Docs/Support/generate-text-files.pl Perl script to make sure this does not happen again (I only discovered this because the Do-pkg script was not able to add the ReadMe.txt to the Apple Disk image because it ran out of disk space due to the size of the file) --- Docs/Makefile.am | 2 +- Docs/Support/generate-text-files.pl | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Docs/Makefile.am b/Docs/Makefile.am index f3df055a7dd..0beaa44c7eb 100644 --- a/Docs/Makefile.am +++ b/Docs/Makefile.am @@ -208,7 +208,7 @@ INSTALL-BINARY: mysql.info $(GT) perl -w $(GT) mysql.info "LGPL license" "Function Index" > $@ ../support-files/MacOSX/ReadMe.txt: mysql.info $(GT) - perl -w $(GT) mysql.info "Mac OS X installation" "Netware installation" > $@ + perl -w $(GT) mysql.info "Mac OS X installation" "NetWare installation" > $@ # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/Docs/Support/generate-text-files.pl b/Docs/Support/generate-text-files.pl index 570e579d926..6470baaa6e9 100755 --- a/Docs/Support/generate-text-files.pl +++ b/Docs/Support/generate-text-files.pl @@ -1,11 +1,11 @@ -#!/my/gnu/bin/perl -w -*- perl -*- +#!/usr/bin/perl -w -*- perl -*- # Generate text files from top directory from the manual. $from = shift(@ARGV); $fnode = shift(@ARGV); $tnode = shift(@ARGV); -open(IN, "$from") || die; +open(IN, "$from") || die "Cannot open $from: $!"; $in = 0; @@ -19,7 +19,7 @@ while () } elsif (/^File: mysql.info/ || (/^/)) { - # Just Skip node begginigs + # Just Skip node beginnings } else { @@ -38,3 +38,6 @@ while () } close(IN); + +die "Could not find node \"$tnode\"" if ($in == 1); +exit 0; From 8b39795b1c7d39e116f10a91ef172e19abe4b878 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 16 Jul 2003 17:13:45 +0200 Subject: [PATCH 178/237] - heavily reworked the comments and layout of the new sample my.cnf file as requested by PeterZ --- support-files/my-innodb-heavy-4G.cnf.sh | 566 +++++++++++++----------- 1 file changed, 303 insertions(+), 263 deletions(-) diff --git a/support-files/my-innodb-heavy-4G.cnf.sh b/support-files/my-innodb-heavy-4G.cnf.sh index b8c49bbf0bc..ed2c2ce9dfd 100644 --- a/support-files/my-innodb-heavy-4G.cnf.sh +++ b/support-files/my-innodb-heavy-4G.cnf.sh @@ -1,244 +1,254 @@ #BEGIN CONFIG INFO -#DESCR: 4G,Innodb only,ACID, Few Connections heavy queries +#DESCR: 4GB RAM, InnoDB only, ACID, few connections, heavy queries #TYPE: SYSTEM #END CONFIG INFO -# This is example config file for systems with 4G of memory running mostly MySQL -# using MyISAM only tables and running complex queries with few connections -# - - - - # -# You can copy this file to -# /etc/my.cnf to set global options, -# mysql-data-dir/my.cnf to set server-specific options (in this -# installation this directory is @localstatedir@) or +# This is a MySQL example config file for systems with 4GB of memory +# running mostly MySQL using InnoDB only tables and performing complex +# queries with few connections. +# +# You can copy this file to /etc/my.cnf to set global options, +# mysql-data-dir/my.cnf to set server-specific options +# (@localstatedir@ for this installation) or to # ~/.my.cnf to set user-specific options. # -# One can in this file use all long options that the program supports. -# If you want to know which options a program support, run the program -# with --help option. +# In this file, you can use all long options that the program supports. +# If you want to know the options a program supports, run the program +# with the "--help" option. +# +# More detailed information about the individual options can also be +# found in the manual. +# - - -# The following options will be passed to all MySQL clients -# But note, only client programs shipped by MySQL are guarantied to read it -# If you wish your software to read this section you would need to specify -# it as an option during MySQL client library initialization +# +# The following options will be read by MySQL client applications. +# Note that only client applications shipped by MySQL are guaranteed +# to read this section. If you want your own MySQL client program to +# honor these values, you need to specify it as an option during the +# MySQL client library initialization. +# [client] -#password = your_password +#password = [your_password] port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ -# ********** Here follows entries for some specific programs +# *** Application-specific options follow here *** +# # The MySQL server +# [mysqld] -# generic configuration options +# generic configuration options port = @MYSQL_TCP_PORT@ socket = @MYSQL_UNIX_ADDR@ - -# Back Log is a number of connection OS can keep in queue, before MySQL -# connection manager thread has processed them. If you have very intensive -# connection rate and experience "connection refused" errors you might need -# to increase this value +# back_log is the number of connections the operating system can keep in +# the listen queue, before the MySQL connection manager thread has +# processed them. If you have a very high connection rate and experience +# "connection refused" errors, you might need to increase this value. +# Check your OS documentation for the maximum value of this parameter. +# Attempting to set back_log higher than your operating system limit +# will have no effect. back_log = 50 - -# Don't listen on a TCP/IP port at all. This can be a security enhancement, -# if all processes that need to connect to mysqld run on the same host. -# All interaction with mysqld must be made via Unix sockets or named pipes. +# Don't listen on a TCP/IP port at all. This can be a security +# enhancement, if all processes that need to connect to mysqld run +# on the same host. All interaction with mysqld must be made via Unix +# sockets or named pipes. # Note that using this option without enabling named pipes on Windows # (via the "enable-named-pipe" option) will render mysqld useless! #skip-networking -# Maximum amount of concurrent sessions MySQL server will allow -# One of these connections will be reserved for user with SUPER privelege -# to allow administrator to login even if server is overloaded. +# The maximum amount of concurrent sessions the MySQL server will +# allow. One of these connections will be reserved for a user with +# SUPER privileges to allow the administrator to login even if the +# connection limit has been reached. max_connections = 100 - -# Maximum amount of errors allowed per host. If this limit is reached -# host will be blocked from connection MySQL server until "flush hosts" -# is run or server restart. Invalid passwords as any other errors at -# connect phase results in increasing this value. See -# Aborted_Connects status variable for global counter. +# Maximum amount of errors allowed per host. If this limit is reached, +# the host will be blocked from connecting to the MySQL server until +# "FLUSH HOSTS" has been run or the server was restarted. Invalid +# passwords and other errors during the connect phase result in +# increasing this value. See the "Aborted_Connects" status variable for +# global counter. max_connect_errors = 10 - -# Amount of tables server can keep open at the time. Each table -# may require up to 2 file handlers (for MERGE tables even more) -# so make sure to have amount of open files allowed at least 4096 -# see open-files-limit in [mysqld_safe] +# The number of open tables for all threads. Increasing this value +# increases the number of file descriptors that mysqld requires. +# Therefore you have to make sure to set the amount of open files +# allowed to at least 4096 in the variable "open-files-limit" in +# section [mysqld_safe] table_cache = 2048 -# Do not use file level locking. Enabled file locking give performance -# hit, so use it only in case you have serveral database instances -# running on the same files (note some restrictions still apply!) -# or if you use other software relaying on locking MyISAM tables -# on file level -#enable-locking +# Enable external file level locking. Enabled file locking will have a +# negative impact on performance, so only use it in case you have +# multiple database instances running on the same files (note some +# restrictions still apply!) or if you use other software relying on +# locking MyISAM tables on file level. +#external-locking -# This packets limits maximum size of BLOB server can handle -# as well as maximum query size server can process -# enlarged dynamically, for each connection +# The maximum size of a query packet the server can handle as well as +# maximum query size server can process (Important when working with +# large BLOBs). enlarged dynamically, for each connection. max_allowed_packet = 16M -# Binary log cache is used for logging transactions to binary log -# all statements from transactions are buffered in binary log cache -# and wrote to the binary log at once on commit -# if transaction is large than this value disk temporary file is used. -# This buffer is allocated per connection on first update statement -# in transaction +# The size of the cache to hold the SQL statements for the binary log +# during a transaction. If you often use big, multi-statement +# transactions you can increase this value to get more performance. All +# statements from transactions are buffered in the binary log cache and +# are being written to the binary log at once after the COMMIT. If the +# transaction is larger than this value, temporary file on disk is used +# instead. This buffer is allocated per connection on first update +# statement in transaction binlog_cache_size = 1M +# Maximum allowed size for a single HEAP (in memory) table. This option +# is a protection against the accidential creation of a very large HEAP +# table which could otherwise use up all memory resources. +max_heap_table_size = 64M -# Maximum allowed size for single HEAP (in memory) table -# This option is protection from accidential creation of the HEAP -# table which would take all the memory resources -max_heap_table_size=64M - - -# Sort buffer used to perform sorts for some of ORDER BY and -# GROUP BY queries. If sorted data does not fit into sort buffer -# Disk based merge sort is used - See sort_merge_passes. -# Allocated per thread if sort is needed +# Sort buffer is used to perform sorts for some ORDER BY and GROUP BY +# queries. If sorted data does not fit into the sort buffer, a disk +# based merge sort is used instead - See "sort_merge_passes". Allocated +# per thread if sort is needed. sort_buffer_size = 8M -# This buffer is used for optimization of full joins (joins without indexes) -# Such joins are very bad for performance in most cases anyway, but having -# this variable large reduces performance impact. -# see select_full_join status variable for full joins count -# Allocated per thread if full join is found -join_buffer_size=8M +# This buffer is used for the optimization of full JOINs (JOINs without +# indexes). Such JOINs are very bad for performance in most cases +# anyway, but setting this variable to a large value reduces the +# performance impact. See the "select_full_join" status variable for a +# count of full JOINs. Allocated per thread if full join is found +join_buffer_size = 8M - -# Cache threads on disconnect instead of destroying them -# thread cache allows to greatly reduce amount of thread -# creations needed if you have a lot of connections +# How many threads we should keep in a cache for reuse. When a client +# disconnects, the client's threads are put in the cache if there aren't +# more than thread_cache_size threads from before. This greatly reduces +# the amount of thread creations needed if you have a lot of new +# connections. (Normally this doesn't give a notable performance +# improvement if you have a good thread implementation.) thread_cache = 8 - -# Try number of CPU's*(2..4) for thread_concurrency -# This value makes sense only on few systems (as Solaris) -# which support thread_concurrency() setting +# This permits the application to give the threads system a hint for the +# desired number of threads that should be run at the same time. This +# value only makes sense on systems that support the thread_concurrency() +# function call (Sun Solaris, for example). +# You should try [number of CPUs]*(2..4) for thread_concurrency thread_concurrency = 8 - -# Query cache is used to cache SELECT results and later return -# them without actual query execution for exactly the same query -# Having query cache enabled may give great benefit if your have -# typical queries and rarely changed tabled -# see Qcache_lowmem_prunes status variable to check if current -# value is enough for your load -# Note: In case your table change all the time or you never have -# textually same queries query cache maay bring slowdown -# instead of performance improvement +# Query cache is used to cache SELECT results and later return them +# without actual executing the same query once again. Having the query +# cache enabled may result in significant speed improvements, if your +# have a lot of identical queries and rarely changing tables. See the +# "Qcache_lowmem_prunes" status variable to check if the current value +# is high enough for your load. +# Note: In case your tables change very often or if your queries are +# textually different every time, the query cache may result in a +# slowdown instead of a performance improvement. query_cache_size = 64M -# Cache only result sets which are smaller than this limit -# This setting is protection of very large result set overwriting -# all queries in query cache +# Only cache result sets that are smaller than this limit. This is to +# protect the query cache of a very large result set overwriting all +# other query results. query_cache_limit = 2M -# Minimum word length to be indexed by full text search index -# you might wish to decrease it if you need to search on shorter words +# Minimum word length to be indexed by the full text search index. +# You might wish to decrease it if you need to search for shorter words. +# Note that you need to rebuild your FULLTEXT index, after you have +# modified this value. ft_min_word_len = 4 -# If your system supports memlock() function you might use this option -# while running MySQL to keep it locking in memory, avoid potential -# swapping out in case of high memory pressure. Good for performance. +# If your system supports the memlock() function call, you might want to +# enable this option while running MySQL to keep it locked in memory and +# to avoid potential swapping out in case of high memory pressure. Good +# for performance. #memlock -# Table type which is used by default, if not specified by CREATE TABLE -# it affects only tables explicitly created by user. +# Table type which is used by default when creating new tables, if not +# specified differently during the CREATE TABLE statement. default_table_type = MYISAM -# Thread stack size to use. This amount of memory is always reserved at -# connection time. MySQL itself usually needs no more than 64K of memory, -# while if you use your own stack hungry UDF functions or OS requires more -# stack for some operations, you might need to set it higher +# Thread stack size to use. This amount of memory is always reserved at +# connection time. MySQL itself usually needs no more than 64K of +# memory, while if you use your own stack hungry UDF functions or your +# OS requires more stack for some operations, you might need to set this +# to a higher value. thread_stack = 192K -# Set default transaction isolation level. Levels available are: +# Set the default transaction isolation level. Levels available are: # READ-UNCOMMITED, READ-COMMITED, REPEATABLE-READ, SERIALIZABLE transaction_isolation = REPEATABLE-READ -# Maximum size for internal in memory temporary table. If table -# grows larger it is automatically converted to disk based table -# This limitaion is for single table. There can be many of them. +# Maximum size for internal (in-memory) temporary tables. If a table +# grows larger than this value, it is automatically converted to disk +# based table This limitation is for a single table. There can be many +# of them. tmp_table_size = 64M -# binary logging is required for acting MASTER in replication -# You also need binary log if you need ability to do point -# in time recovery from your latest backup +# Enable binary logging. This is required for acting as a MASTER in a +# replication configuration. You also need the binary log if you need +# the ability to do point in time recovery from your latest backup. log_bin -# If you're using chaining replication A->B->C you might wish to -# turn on this option on server B. It makes updates done by -# slave thread also logged in binary log. Normally they are not +# If you're using replication with chained slaves (A->B->C), you need to +# enable this option on server B. It enables logging of updates done by +# the slave thread into the slave's binary log. #log_slave_updates - -# Full query log. Every query (even with incorrect syntax) server gets goes here. -# Useful for debugging. Normally is disabled in production +# Enable the full query log. Every query (even ones with incorrect +# syntax) that the server receives will be logged. This is useful for +# debugging, it is usually disabled in production use. #log -# If you have any problems with MySQL server you might enable Warnings logging and -# examine error log for possible explanations. +# Print warnings to the error log file. If you have any problem with +# MySQL you should enable logging of warnings and examine the error log +# for possible explanations. #log_warnings -# Log slow queries. Slow queries are queries which take more than defined amount of time -# or which do not use indexes well, if log_long_format is enabled -# It is notmally good idea to have this on if you frequently add new queries to the system +# Log slow queries. Slow queries are queries which take more than the +# amount of time defined in "long_query_time" or which do not use +# indexes well, if log_long_format is enabled. It is normally good idea +# to have this turned on if you frequently add new queries to the +# system. log_slow_queries - -# All queries taking more than this amount of time will be trated as slow. Do not use value 1 -# here as this will result even in very fast queries logged sometimes, as MySQL measures time with -# second accuracy only. +# All queries taking more than this amount of time (in seconds) will be +# trated as slow. Do not use "1" as a value here, as this will result in +# even very fast queries being logged from time to time (as MySQL +# currently measures time with second accuracy only). long_query_time = 2 -# Log more information in slow query log. Normally it is good to have this on. -# It results in logging of queries not using indexes additionally to long running queries. +# Log more information in the slow query log. Normally it is good to +# have this turned on. This will enable logging of queries that are not +# using indexes in addition to long running queries. log_long_format +# The directory used by MySQL for storing temporary files. For example, +# it is used to perform disk based large sorts, as well as for internal +# and explicit temporary tables. It might be good to put it on a +# swapfs/tmpfs filesystem, if you do not create very large temporary +# files. Alternatively you can put it on dedicated disk. You can +# specify multiple paths here by separating them by ";" - they will then +# be used in a round-robin fashion. +#tmpdir = /tmp -# Temporary directory is used by MySQL for storing temporary files, for example -# used to do disk based large sorts, as well as for internal and explicit -# temporary tables. -# It might be good to set it to swapfs/tmpfs filesystem if you do not have very -# large temporary files created or set it to dedicated disk -# You can specify several paths here spliting them by ";" they will be used in -# round-robin fashion -#tmpdir = /tmp +# *** Replication related settings -#*** Replication related settings - - -# This value is required both for master ans slave -# If you have single master it is typical to use value 1 for it -# required unique id between 1 and 2^32 - 1 -# defaults to 1 if master-host is not set -# but will not function as a master if omitted +# Unique server identification number between 1 and 2^32-1. This value +# is required for both master and slave hosts. It defaults to 1 if +# "master-host" is not set, but will MySQL will not function as a master +# if it is omitted. server-id = 1 - -# To configure this server as Replication Slave you will need -# to set its server_id to some unique value, different from Master -# and all slaves in the group. -# You also can disable log-bin as logs are not required (while recomended) -# for slaves -# +# Replication Slave (comment out master section to use this) # -# The recomended way to set MASTER settings for the slave are: -# Use the CHANGE MASTER TO command (fully described in our manual) - +# To configure this host as a replication slave, you can choose between +# two methods : +# +# 1) Use the CHANGE MASTER TO command (fully described in our manual) - # the syntax is: # # CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=, @@ -252,191 +262,221 @@ server-id = 1 # CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306, # MASTER_USER='joe', MASTER_PASSWORD='secret'; # -# However if you need to replicate slave configuration over several boxes -# you can use old approach: +# OR # -# Set the variables below. However, in case you choose this method, then +# 2) Set the variables below. However, in case you choose this method, then # start replication for the first time (even unsuccessfully, for example # if you mistyped the password in master-password and the slave fails to # connect), the slave will create a master.info file, and any later -# change in this file to the variables' values below will be ignored and +# changes in this file to the variable values below will be ignored and # overridden by the content of the master.info file, unless you shutdown # the slave server, delete master.info and restart the slaver server. # For that reason, you may want to leave the lines below untouched # (commented) and instead use CHANGE MASTER TO (see above) # +# required unique id between 2 and 2^32 - 1 +# (and different from the master) +# defaults to 2 if master-host is set +# but will not function as a slave if omitted +#server-id = 2 # # The replication master for this slave - required -#master-host = +#master-host = # # The username the slave will use for authentication when connecting # to the master - required -#master-user = +#master-user = # # The password the slave will authenticate with when connecting to # the master - required -#master-password = +#master-password = # # The port the master is listening on. # optional - defaults to 3306 -#master-port = +#master-port = -# Make Slave ReadOnly. Only user with SUPER privelege and slave -# thread will be able to modify it. You might use it to ensure -# no applications will accidently modify slave instead of master +# Make the slave read-only. Only users with the SUPER privilege and the +# replication slave thread will be able to modify data on it. You can +# use this to ensure that no applications will accidently modify data on +# the slave instead of the master #read_only - #*** MyISAM Specific options -# Size of Key Buffer, used to cache index blocks for MyISAM tables -# Do not set it larger than 30% of available memory, as some memory -# is required by OS to cache rows. -# Even if you're not using MyISAM tables still set it to 8-64M -# as it will be used for internal temporary disk tables. +# Size of the Key Buffer, used to cache index blocks for MyISAM tables. +# Do not set it larger than 30% of your available memory, as some memory +# is also required by the OS to cache rows. Even if you're not using +# MyISAM tables, you should still set it to 8-64M as it will also be +# used for internal temporary disk tables. key_buffer_size = 32M -# Size of buffer used for doing full table scans for MyISAM tables -# allocated per thread, as full scan is needed +# Size of the buffer used for doing full table scans of MyISAM tables. +# Allocated per thread, if a full scan is needed. read_buffer_size = 2M -# Buffer is used for caching the rows while doing Sorts -# Allocated per thread, then needed +# When reading rows in sorted order after a sort, the rows are read +# through this buffer to avoid a disk seeks. You can improve ORDER BY +# performance a lot, if set this to a high value. +# Allocated per thread, when needed. read_rnd_buffer_size = 16M -# The bulk insert tree is used for optimization of index modification -# for bulk inserts (hundreds+ values) and LOAD DATA INFILE -# Do not set larger than key_buffer_size for optimal performance -# This buffer is allocated than bulk insert is detected +# MyISAM uses special tree-like cache to make bulk inserts (that is, +# INSERT ... SELECT, INSERT ... VALUES (...), (...), ..., and LOAD DATA +# INFILE) faster. This variable limits the size of the cache tree in +# bytes per thread. Setting it to 0 will disable this optimisation. Do +# not set it larger than "key_buffer_size" for optimal performance. +# This buffer is allocated when a bulk insert is detected. bulk_insert_buffer_size = 64M - -# This buffer is allocated than MySQL needs to rebuild the Index, -# in REPAIR, OPTIMZE, ALTER table statements as well as in -# LOAD DATA INFILE to empty table -# it is allocated per thread so be careful with large settings. +# This buffer is allocated when MySQL needs to rebuild the index in +# REPAIR, OPTIMZE, ALTER table statements as well as in LOAD DATA INFILE +# into an empty table. It is allocated per thread so be careful with +# large settings. myisam_sort_buffer_size = 128M -# Maximum size of temporary (sort) file index rebuild can use. -# If sort is estimated to take larger amount of space, mush slower -# (keycache) index rebuild method will be used +# The maximum size of the temporary file MySQL is allowed to use while +# recreating the index (during REPAIR, ALTER TABLE or LOAD DATA INFILE. +# If the file-size would be bigger than this, the index will be created +# through the key cache (which is slower). myisam_max_sort_file_size = 10G -# Use sort method in case the difference between sort file and -# Table index file is estimated to be less than this value +# If the temporary file used for fast index creation would be bigger +# than using the key cache by the amount specified here, then prefer the +# key cache method. This is mainly used to force long character keys in +# large tables to use the slower key cache method to create the index. myisam_max_extra_sort_file_size = 10G -# If table has more than one index MyISAM can use more than one thread -# to repair them in parallel. It makes sense if you have multiple of -# CPUs and planty of memory. +# If a table has more than one index, MyISAM can use more than one +# thread to repair them by sorting in parallel. This makes sense if you +# have multiple CPUs and plenty of memory. myisam_repair_threads = 1 -# Automatically check and repair not properly closed MyISAM tables +# Automatically check and repair not properly closed MyISAM tables. myisam_recover +# *** BDB Specific options *** -#*** BDB Specific options - -# Use this option if you have BDB tables enabled but you do not plan to use them +# Use this option if you run a MySQL server with BDB support enabled but +# you do not plan to use it. This will save memory and may speed up some +# things. skip-bdb -#*** INNODB Specific options +# *** INNODB Specific options *** -# Use this option if you have INNODB tables enabled but you do not plan to use them +# Use this option if you have a MySQL server with InnoDB support enabled +# but you do not plan to use it. This will save memory and disk space +# and speed up some things. #skip-innodb -# Additional memory pool is used by Innodb to store metadata information. -# If Innodb needs more memory for this purpose to allocate it from OS -# As it is fast enough on most recent OS you normally do not need to set it higher -# SHOW INNODB STATUS will show current amount of it in use +# Additional memory pool that is used by InnoDB to store metadata +# information. If InnoDB requires more memory for this purpose it will +# start to allocate it from the OS. As this is fast enough on most +# recent operating systems, you normally do not need to change this +# value. SHOW INNODB STATUS will display the current amount used. innodb_additional_mem_pool_size = 16M -# Innodb, unlike MyISAM uses bufferpool to cache both indexes and row data -# so you would normally wish to have it large up to 50-70% of your memory size -# Note on 32bit systems you might be limited to 2-3.5G of user level memory -# per process so do not set it too high. +# InnoDB, unlike MyISAM, uses a buffer pool to cache both indexes and +# row data. The bigger you set this the less disk I/O is needed to +# access data in tables. On a dedicated database server you may set this +# parameter up to 80% of the machine physical memory size. Do not set it +# too large, though, because competition of the physical memory may +# cause paging in the operating system. Note that on 32bit systems you +# might be limited to 2-3.5G of user level memory per process, so do not +# set it too high. innodb_buffer_pool_size = 2G -# Innodb stores data in one or several files forming tablespace. If you have -# single logical drive for your data, single autoextending file would be good enough -# In other case single file per device is often good choice. -# You may setup Innodb to use Raw disk partitions as well. Refer to the manual. +# InnoDB stores data in one or more data files forming the tablespace. +# If you have a single logical drive for your data, a single +# autoextending file would be good enough. In other cases, a single file +# per device is often a good choice. You can configure InnoDB to use raw +# disk partitions as well - please refer to the manual for more info +# about this. innodb_data_file_path = ibdata1:10M:autoextend +# Set this option if you would like the InnoDB tablespace files to be +# stored in another location. By default this is the MySQL datadir. +#innodb_data_home_dir = -# Set this option if you would like Innodb tablespace files to be stored in other -# location. Default is MySQL datadir. -#innodb_data_home_dir - -# Number of IO threads to use for async IO operations. This value is hardcoded to -# 4 on Unix +# Number of IO threads to use for async IO operations. This value is +# hardcoded to 4 on Unix, but on Windows disk I/O may benefit from a +# larger number. innodb_file_io_threads = 4 - -# If you run into Innodb tablespace corruption, setting this to nonzero value will -# likely help you to dump your tables. Start from value 1 and increase it until -# you're able to dump the table successfully. +# If you run into InnoDB tablespace corruption, setting this to a nonzero +# value will likely help you to dump your tables. Start from value 1 and +# increase it until you're able to dump the table successfully. #innodb_force_recovery=1 -# Number of threads allowed inside of Innodb kernel. Best setting highly depends -# on the application, hardware as well as OS scheduler properties -# Too high value may lead to thread thrashing +# Number of threads allowed inside the InnoDB kernel. The optimal value +# depends highly on the application, hardware as well as the OS +# scheduler properties. A too high value may lead to thread thrashing. innodb_thread_concurrency = 16 - -# If set to 1 Innodb will flush(fsync) logs to the disk at each transaction commit -# which offers full ACID behavior, however if you can afford few last commited transaction -# lost you can set this value to 2 or 0. Innodb will anyway flush the log file once -# per second. 0 - do not flush file at all. 2 - flush it to OS buffers but not to the disk. +# If set to 1, InnoDB will flush (fsync) the transaction logs to the +# disk at each commit, which offers full ACID behavior. If you are +# willing to compromise this safety, and you are running small +# transactions, you may set this to 0 or 2 to reduce disk I/O to the +# logs. Value 0 means that the log is only written to the log file and +# the log file flushed to disk approximately once per second. Value 2 +# means the log is written to the log file at each commit, but the log +# file is only flushed to disk approximately once per second. innodb_flush_log_at_trx_commit = 1 - -# Innodb uses fast shutdown by default. However you can disable it to make Innodb to do -# purge and Insert buffer merge on shutdown. It may increase shutdown time a lot but -# Innodb will have not need to do it after next startup +# Speed up InnoDB shutdown. This will disable InnoDB to do a full purge +# and insert buffer merge on shutdown. It may increase shutdown time a +# lot, but InnoDB will have to do it on the next startup instead. #innodb_fast_shutdown -# Buffer Innodb shall use for buffering log data. As soon as it is full Innodb -# will have to flush it. As it is flushed once per second anyway even with -# long transactions it does not make sense to have it very large. +# The size of the buffer InnoDB uses for buffering log data. As soon as +# it is full, InnoDB will have to flush it to disk. As it is flushed +# once per second anyway, it does not make sense to have it very large +# (even with long transactions). innodb_log_buffer_size = 8M -# Size of log file in group. You shall set combined size of log files large 25%-100% of -# your buffer pool size to avoid not needed buffer pool flush activity on log file -# overwrite. Note however larger logfile size will increase time needed for recovery -# process. +# Size of each log file in a log group. You should set the combined size +# of log files to about 25%-100% of your buffer pool size to avoid +# unneeded buffer pool flush activity on log file overwrite. However, +# note that a larger logfile size will increase the time needed for the +# recovery process. innodb_log_file_size = 256M -# Total number of files in the log group. Value 2-3 is usually good enough. +# Total number of files in the log group. A value of 2-3 is usually good +# enough. innodb_log_files_in_group = 3 -# Location for Innodb log files. Default is MySQL datadir. You may wish to -# point it to dedicated hard drive or RAID1 volume for improved performance +# Location of the InnoDB log files. Default is the MySQL datadir. You +# may wish to point it to a dedicated hard drive or a RAID1 volume for +# improved performance #innodb_log_group_home_dir -# Maximum allowed Percentage of dirty pages in Innodb buffer pool. -# If it is reached Innodb will start flushing them agressively not to run -# out of clean pages at all. This is a soft limit, not guarantied to be held. +# Maximum allowed percentage of dirty pages in the InnoDB buffer pool. +# If it is reached, InnoDB will start flushing them out agressively to +# not run out of clean pages at all. This is a soft limit, not +# guaranteed to be held. innodb_max_dirty_pages_pct = 90 +# The flush method InnoDB will use for Log. The tablespace always uses +# doublewrite flush logic. The default value is "fdatasync", another +# option is "O_DSYNC". +#innodb_flush_method=O_DSYNC -# Set flush method Innodb will use for Log. Tablespace always uses doublewrite flush logic. -#innodb_flush_method - -# How long Innodb transaction shall wait for lock to be granted before giving up. -# This value does not correspond to deadlock resolution. Innodb will detect Deadlock -# as soon as it is formed. +# How long an InnoDB transaction should wait for a lock to be granted +# before being rolled back. InnoDB automatically detects transaction +# deadlocks in its own lock table and rolls back the transaction. If you +# use the LOCK TABLES command, or other transaction-safe storage engines +# than InnoDB in the same transaction, then a deadlock may arise which +# InnoDB cannot notice. In cases like this the timeout is useful to +# resolve the situation. innodb_lock_wait_timeout = 120 - [mysqldump] -# Do not buffer whole result set in memory before writing it to file -# required for dumping very large tables +# Do not buffer the whole result set in memory before writing it to +# file. Required for dumping very large tables quick max_allowed_packet = 16M @@ -444,7 +484,7 @@ max_allowed_packet = 16M [mysql] no-auto-rehash -# Remove the next comment character if you are not familiar with SQL +# Only allow UPDATEs and DELETEs that use keys. #safe-updates [isamchk] @@ -463,7 +503,7 @@ write_buffer = 8M interactive-timeout [mysqld_safe] -# Increase amount of open files allowed per process -# Warning: Make sure you have global system limit high enough -# The high value is required for large number of opened tables +# Increase the amount of open files allowed per process. Warning: Make +# sure you have set the global system limit high enough! The high value +# is required for a large number of opened tables open-files-limit = 8192 From ac08d278b9fb895b6680d9090456ef5851f63d54 Mon Sep 17 00:00:00 2001 From: "vva@eagle.mysql.r18.ru" <> Date: Wed, 16 Jul 2003 18:15:35 -0400 Subject: [PATCH 179/237] fixed bug Bug #683 (Prompt for password doesn't go to console for Windows) --- client/get_password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/get_password.c b/client/get_password.c index 9928d24de32..5d78656ab0a 100644 --- a/client/get_password.c +++ b/client/get_password.c @@ -71,7 +71,7 @@ char *get_tty_password(char *opt_message) char *pos=to,*end=to+sizeof(to)-1; int i=0; DBUG_ENTER("get_tty_password"); - fprintf(stderr,opt_message ? opt_message : "Enter password: "); + _cputs(opt_message ? opt_message : "Enter password: "); for (;;) { char tmp; From 6714563186b8aa0d542c7b052aa5f8fc2fbb038d Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Thu, 17 Jul 2003 20:17:46 +0200 Subject: [PATCH 180/237] my_strnncoll_latin1_de rewritten from scratch. Bug with overlapping combos went away. --- mysql-test/r/ctype_latin1_de.result | 3 + mysql-test/t/ctype_latin1_de.test | 4 + strings/ctype-latin1_de.c | 157 +++++++++------------------- 3 files changed, 56 insertions(+), 108 deletions(-) diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result index 630fef9b679..28394d9533a 100644 --- a/mysql-test/r/ctype_latin1_de.result +++ b/mysql-test/r/ctype_latin1_de.result @@ -196,6 +196,9 @@ strcmp(' select strcmp('u','öa'),strcmp('u','ö'); strcmp('u','öa') strcmp('u','ö') 1 1 +select strcmp('sä', 'ßa'), strcmp('aä', 'äx'); +strcmp('sä', 'ßa') strcmp('aä', 'äx') +-1 -1 create table t1 (a varchar(10), key(a), fulltext (a)); insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); select * from t1 where a like "abc%"; diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test index 6353650f420..3a0f2658969 100644 --- a/mysql-test/t/ctype_latin1_de.test +++ b/mysql-test/t/ctype_latin1_de.test @@ -34,6 +34,10 @@ select strcmp('af',' select strcmp('ßa','ss'),strcmp('ssa','ß'),strcmp('sssb','sßa'),strcmp('ß','s'); select strcmp('u','öa'),strcmp('u','ö'); +# +# overlapping combo's +# +select strcmp('sä', 'ßa'), strcmp('aä', 'äx'); # # Some other simple tests with the current character set # diff --git a/strings/ctype-latin1_de.c b/strings/ctype-latin1_de.c index 01d377f91c3..5b7a68fb967 100644 --- a/strings/ctype-latin1_de.c +++ b/strings/ctype-latin1_de.c @@ -102,6 +102,7 @@ uchar to_upper_latin1_de[] = { * Ü, ü, Ö, ö, Ä, ä */ +/* QQ: why it is necessary ? */ uchar sort_order_latin1_de[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -121,6 +122,41 @@ uchar sort_order_latin1_de[] = { 68, 78, 79, 79, 79, 79,214,247,216, 85, 85, 85,220, 89,222, 89 }; + +/* same as sort_order_latin_de, but maps ALL accented chars to unacented ones */ +uchar combo1map[]={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127, + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, + 65, 65, 65, 65, 65, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73, + 68, 78, 79, 79, 79, 79, 79,215,216, 85, 85, 85, 85, 89,222, 83, + 65, 65, 65, 65, 65, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73, + 68, 78, 79, 79, 79, 79, 79,247,216, 85, 85, 85, 85, 89,222, 89 +}; + +uchar combo2map[]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,69, 0, 0,83, 0, 0, 0, 0,69, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,69, 0, 0, 0, 0 +}; + +/* no longer needed #define L1_AE 196 #define L1_ae 228 #define L1_OE 214 @@ -128,7 +164,7 @@ uchar sort_order_latin1_de[] = { #define L1_UE 220 #define L1_ue 252 #define L1_ss 223 - +*/ /* Some notes about the following comparison rules: @@ -143,95 +179,23 @@ uchar sort_order_latin1_de[] = { sort_order_latin_de[] at all */ - -#define CHECK_S1_COMBO(ch1, ch2, str1, str1_end, res_if_str1_smaller, str2, fst, snd, accent) \ - /* Invariant: ch1 == fst == sort_order_latin1_de[accent] && ch1 != ch2 */ \ - if (ch2 != accent) \ - { \ - ch1= fst; \ - goto normal; \ - } \ - if (str1 == str1_end) \ - return res_if_str1_smaller; \ - { \ - int diff = (int) sort_order_latin1_de[*str1] - snd; \ - if (diff) \ - return diff*(-(res_if_str1_smaller)); \ - /* They are equal (e.g., "Ae" == 'ä') */ \ - str1++; \ - } - - int my_strnncoll_latin1_de(const uchar * s1, int len1, const uchar * s2, int len2) { const uchar *e1 = s1 + len1; const uchar *e2 = s2 + len2; + uchar c1, c12=0, c2, c22=0; - while (s1 < e1 && s2 < e2) + while ((s1 < e1 || c12) && (s2 < e2 || c22)) { - /* - Because sort_order_latin1_de doesn't convert 'Ä', Ü or ß we - can use it here. - */ - uchar c1 = sort_order_latin1_de[*s1++]; - uchar c2 = sort_order_latin1_de[*s2++]; - if (c1 != c2) - { - switch (c1) { - case 'A': - CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'A', 'E', L1_AE); - break; - case 'O': - CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'O', 'E', L1_OE); - break; - case 'U': - CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'U', 'E', L1_UE); - break; - case 'S': - CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'S', 'S', L1_ss); - break; - case L1_AE: - CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'A', 'E', 'A'); - break; - case L1_OE: - CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'O', 'E', 'O'); - break; - case L1_UE: - CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'U', 'E', 'U'); - break; - case L1_ss: - CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'S', 'S', 'S'); - break; - default: - /* - Handle the case where 'c2' is a special character - If this is true, we know that c1 can't match this character. - */ - normal: - switch (c2) { - case L1_AE: - return (int) c1 - (int) 'A'; - case L1_OE: - return (int) c1 - (int) 'O'; - case L1_UE: - return (int) c1 - (int) 'U'; - case L1_ss: - return (int) c1 - (int) 'S'; - default: - { - int diff= (int) c1 - (int) c2; - if (diff) - return diff; - } - break; - } - } - } + if (c12) { c1=c12; c12=0; } else { c12=combo2map[*s1]; c1=combo1map[*s1++]; } + if (c22) { c2=c22; c22=0; } else { c22=combo2map[*s2]; c2=combo1map[*s2++]; } + if (c1 != c2) return (int)c1 - (int)c2; } + /* A simple test of string lengths won't work -- we test to see * which string ran out first */ - return s1 < e1 ? 1 : s2 < e2 ? -1 : 0; + return (s1 < e1 || c12)? 1 : (s2 < e2 || c22)? -1 : 0; } @@ -240,35 +204,12 @@ int my_strnxfrm_latin1_de(uchar * dest, const uchar * src, int len, int srclen) const uchar *dest_orig = dest; const uchar *de = dest + len; const uchar *se = src + srclen; - while (src < se && dest < de) + for ( ; src < se && dest < de ; src++) { - uchar chr=sort_order_latin1_de[*src]; - switch (chr) { - case L1_AE: - *dest++ = 'A'; - if (dest < de) - *dest++ = 'E'; - break; - case L1_OE: - *dest++ = 'O'; - if (dest < de) - *dest++ = 'E'; - break; - case L1_UE: - *dest++ = 'U'; - if (dest < de) - *dest++ = 'E'; - break; - case L1_ss: - *dest++ = 'S'; - if (dest < de) - *dest++ = 'S'; - break; - default: - *dest++= chr; - break; - } - ++src; + uchar chr=combo1map[*src]; + *dest++=chr; + if ((chr=combo2map[*src]) && dest < de) + *dest++=chr; } return dest - dest_orig; } From 7b8a54b51281ed4b859af7850e7106c4de4d975e Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Fri, 18 Jul 2003 04:04:24 +0300 Subject: [PATCH 181/237] Fixed memory overrun when doing REPAIR on table with multi-part auto_increment key where one part was a packed CHAR --- myisam/mi_check.c | 22 ++++++++++++++++++---- myisam/mi_key.c | 2 +- mysql-test/r/insert_select.result | 5 +++++ mysql-test/t/insert_select.test | 10 ++++++++++ mysys/safemalloc.c | 6 +++--- sql/sql_acl.cc | 6 +++++- 6 files changed, 42 insertions(+), 9 deletions(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 92641cce13a..6caacd95386 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -896,7 +896,8 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend) if (_mi_rec_unpack(info,record,info->rec_buff,block_info.rec_len) == MY_FILE_ERROR) { - mi_check_print_error(param,"Found wrong record at %s", llstr(start_recpos,llbuff)); + mi_check_print_error(param,"Found wrong record at %s", + llstr(start_recpos,llbuff)); got_error=1; } else @@ -3611,6 +3612,7 @@ err: void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, my_bool repair_only) { + byte *record; if (!info->s->base.auto_key || !(((ulonglong) 1 << (info->s->base.auto_key-1) & info->s->state.key_map))) @@ -3624,13 +3626,24 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, if (!(param->testflag & T_SILENT) && !(param->testflag & T_REP)) printf("Updating MyISAM file: %s\n", param->isam_file_name); - /* We have to use keyread here as a normal read uses info->rec_buff */ + /* + We have to use an allocated buffer instead of info->rec_buff as + _mi_put_key_in_record() may use info->rec_buff + */ + if (!(record= (byte*) my_malloc((uint) info->s->base.pack_reclength, + MYF(0)))) + { + mi_check_print_error(param,"Not enough memory for extra record"); + return; + } + mi_extra(info,HA_EXTRA_KEYREAD,0); - if (mi_rlast(info,info->rec_buff, info->s->base.auto_key-1)) + if (mi_rlast(info, record, info->s->base.auto_key-1)) { if (my_errno != HA_ERR_END_OF_FILE) { mi_extra(info,HA_EXTRA_NO_KEYREAD,0); + my_free((char*) record, MYF(0)); mi_check_print_error(param,"%d when reading last record",my_errno); return; } @@ -3642,10 +3655,11 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info, ulonglong auto_increment= (repair_only ? info->s->state.auto_increment : param->auto_increment_value); info->s->state.auto_increment=0; - update_auto_increment(info,info->rec_buff); + update_auto_increment(info, record); set_if_bigger(info->s->state.auto_increment,auto_increment); } mi_extra(info,HA_EXTRA_NO_KEYREAD,0); + my_free((char*) record, MYF(0)); update_state_info(param, info, UPDATE_AUTO_INC); return; } diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 5b167cc9ab0..89f6bc490fa 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -264,7 +264,7 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr, byte *blob_ptr; DBUG_ENTER("_mi_put_key_in_record"); - if (info->blobs && info->s->keyinfo[keynr].flag & HA_VAR_LENGTH_KEY) + if (info->s->base.blobs && info->s->keyinfo[keynr].flag & HA_VAR_LENGTH_KEY) { if (!(blob_ptr= mi_alloc_rec_buff(info, info->s->keyinfo[keynr].keylength, diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index c007191b562..0142ef68993 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -587,3 +587,8 @@ a b 3 t2:3 2 t2:2 drop table t1,t2; +CREATE TABLE t1 ( USID INTEGER UNSIGNED, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User CHAR(32) NOT NULL DEFAULT '', NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL); +CREATE TABLE t2 ( USID INTEGER UNSIGNED AUTO_INCREMENT, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User TEXT NOT NULL, NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL, INDEX(USID,ServerID,NASAddr,SessionID), INDEX(AssignedAddr)); +INSERT INTO t1 VALUES (39,42,'Access-Granted','46','491721000045',2130706433,17690,NULL,NULL,'Localnet','491721000045','49172200000',754974766,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2003-07-18 00:11:21',NULL,NULL,20030718001121); +INSERT INTO t2 SELECT USID, ServerID, State, SessionID, User, NASAddr, NASPort, NASPortType, ConnectSpeed, CarrierType, CallingStationID, CalledStationID, AssignedAddr, SessionTime, PacketsIn, OctetsIn, PacketsOut, OctetsOut, TerminateCause, UnauthTime, AccessRequestTime, AcctStartTime, AcctLastTime, LastModification from t1 LIMIT 1; +drop table t1,t2; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index d115e9c1af6..5c63f3b3bb7 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -122,3 +122,13 @@ select * from t1; replace into t1 select * from t2; select * from t1; drop table t1,t2; + +# +# Test that caused uninitialized memory access in auto_increment_key update +# + +CREATE TABLE t1 ( USID INTEGER UNSIGNED, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User CHAR(32) NOT NULL DEFAULT '', NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL); +CREATE TABLE t2 ( USID INTEGER UNSIGNED AUTO_INCREMENT, ServerID TINYINT UNSIGNED, State ENUM ('unknown', 'Access-Granted', 'Session-Active', 'Session-Closed' ) NOT NULL DEFAULT 'unknown', SessionID CHAR(32), User TEXT NOT NULL, NASAddr INTEGER UNSIGNED, NASPort INTEGER UNSIGNED, NASPortType INTEGER UNSIGNED, ConnectSpeed INTEGER UNSIGNED, CarrierType CHAR(32), CallingStationID CHAR(32), CalledStationID CHAR(32), AssignedAddr INTEGER UNSIGNED, SessionTime INTEGER UNSIGNED, PacketsIn INTEGER UNSIGNED, OctetsIn INTEGER UNSIGNED, PacketsOut INTEGER UNSIGNED, OctetsOut INTEGER UNSIGNED, TerminateCause INTEGER UNSIGNED, UnauthTime TINYINT UNSIGNED, AccessRequestTime DATETIME, AcctStartTime DATETIME, AcctLastTime DATETIME, LastModification TIMESTAMP NOT NULL, INDEX(USID,ServerID,NASAddr,SessionID), INDEX(AssignedAddr)); +INSERT INTO t1 VALUES (39,42,'Access-Granted','46','491721000045',2130706433,17690,NULL,NULL,'Localnet','491721000045','49172200000',754974766,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'2003-07-18 00:11:21',NULL,NULL,20030718001121); +INSERT INTO t2 SELECT USID, ServerID, State, SessionID, User, NASAddr, NASPort, NASPortType, ConnectSpeed, CarrierType, CallingStationID, CalledStationID, AssignedAddr, SessionTime, PacketsIn, OctetsIn, PacketsOut, OctetsOut, TerminateCause, UnauthTime, AccessRequestTime, AcctStartTime, AcctLastTime, LastModification from t1 LIMIT 1; +drop table t1,t2; diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index bd77b4821ff..07c40fd91b6 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -374,11 +374,11 @@ void TERMINATE(FILE *file) { if (file) { - fprintf(file, "Warning: Not freed memory segments: %d\n", + fprintf(file, "Warning: Not freed memory segments: %u\n", sf_malloc_count); (void) fflush(file); } - DBUG_PRINT("safe",("sf_malloc_count: %d", sf_malloc_count)); + DBUG_PRINT("safe",("sf_malloc_count: %u", sf_malloc_count)); } /* @@ -482,7 +482,7 @@ int _sanity(const char *filename, uint lineno) pthread_mutex_lock(&THR_LOCK_malloc); #ifndef PEDANTIC_SAFEMALLOC - if (sf_malloc_tampered && sf_malloc_count < 0) + if (sf_malloc_tampered && (int) sf_malloc_count < 0) sf_malloc_count=0; #endif count=sf_malloc_count; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 697b5d8ffd6..d773aa5bc71 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1136,7 +1136,11 @@ find_acl_user(const char *host, const char *user) { ACL_USER *acl_user=dynamic_element(&acl_users,i,ACL_USER*); DBUG_PRINT("info",("strcmp('%s','%s'), compare_hostname('%s','%s'),", - user,acl_user->user,(host),(acl_user->host))); + user, + acl_user->user ? acl_user->user : "", + host, + acl_user->host.hostname ? acl_user->host.hostname : + "")); if (!acl_user->user && !user[0] || acl_user->user && !strcmp(user,acl_user->user)) { From 2bca1221cd1682a3fd8adc9295d4d834d0ec6ec1 Mon Sep 17 00:00:00 2001 From: "monty@narttu.mysql.fi" <> Date: Fri, 18 Jul 2003 04:37:37 +0300 Subject: [PATCH 182/237] Removed wrong "Found lock of type # that is write and read locked" warnings. --- mysys/thr_lock.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 61616a4cf2b..d5236cb1ef9 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -172,10 +172,13 @@ static int check_lock(struct st_lock_list *list, const char* lock_type, return 0; } + static void check_locks(THR_LOCK *lock, const char *where, my_bool allow_no_locks) { uint old_found_errors=found_errors; + DBUG_ENTER("check_locks"); + if (found_errors < MAX_FOUND_ERRORS) { if (check_lock(&lock->write,"write",where,1,1) | @@ -252,18 +255,21 @@ static void check_locks(THR_LOCK *lock, const char *where, } if (lock->read.data) { - if ((!pthread_equal(lock->write.data->thread, - lock->read.data->thread) && - lock->write.data->type > TL_WRITE_DELAYED && - lock->write.data->type != TL_WRITE_ONLY) || - ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT || - lock->write.data->type == TL_WRITE_ALLOW_WRITE) && - lock->read_no_write_count)) + if (!pthread_equal(lock->write.data->thread, + lock->read.data->thread) && + ((lock->write.data->type > TL_WRITE_DELAYED && + lock->write.data->type != TL_WRITE_ONLY) || + ((lock->write.data->type == TL_WRITE_CONCURRENT_INSERT || + lock->write.data->type == TL_WRITE_ALLOW_WRITE) && + lock->read_no_write_count))) { found_errors++; fprintf(stderr, "Warning at '%s': Found lock of type %d that is write and read locked\n", where, lock->write.data->type); + DBUG_PRINT("warning",("At '%s': Found lock of type %d that is write and read locked\n", + where, lock->write.data->type)); + } } if (lock->read_wait.data) @@ -286,6 +292,7 @@ static void check_locks(THR_LOCK *lock, const char *where, DBUG_PRINT("error",("Found wrong lock")); } } + DBUG_VOID_RETURN; } #else /* EXTRA_DEBUG */ From 428e34813905ee18f276981d5b15354b74725174 Mon Sep 17 00:00:00 2001 From: "monty@mashka.(none)" <> Date: Fri, 18 Jul 2003 12:35:29 +0300 Subject: [PATCH 183/237] Portability fixes for Redhat 9 --- BitKeeper/etc/logging_ok | 1 + acinclude.m4 | 15 ++++++++++++--- vio/viosocket.c | 2 +- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index b70b0a7b381..e6124b4111e 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -56,6 +56,7 @@ monty@bitch.mysql.fi monty@butch. monty@donna.mysql.fi monty@hundin.mysql.fi +monty@mashka.(none) monty@mashka.mysql.fi monty@narttu. monty@narttu.mysql.fi diff --git a/acinclude.m4 b/acinclude.m4 index f7d89ecf35a..3bee4e7a874 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -713,7 +713,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ /usr/include/ssl /opt/ssl/include /opt/openssl/include \ /usr/local/ssl/include /usr/local/include ; do if test -f $d/openssl/ssl.h ; then - OPENSSL_INCLUDE=$d + OPENSSL_INCLUDE=-I$d fi done @@ -724,6 +724,15 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ fi done + # On RedHat 9 we need kerberos to compile openssl + for d in /usr/kerberos/include + do + if test -f $d/krb5.h ; then + OPENSSL_INCLUDE="$OPENSSL_INCLUDE -I$d" + fi + done + + if test -z "$OPENSSL_LIB" -o -z "$OPENSSL_INCLUDE" ; then echo "Could not find an installation of OpenSSL" if test -n "$OPENSSL_LIB" ; then @@ -756,9 +765,9 @@ AC_MSG_CHECKING(for OpenSSL) openssl_libs="-L$OPENSSL_LIB -lssl -lcrypto" # Don't set openssl_includes to /usr/include as this gives us a lot of # compiler warnings when using gcc 3.x - if test "$OPENSSL_INCLUDE" != "/usr/include" + if test "$OPENSSL_INCLUDE" != "-I/usr/include" then - openssl_includes="-I$OPENSSL_INCLUDE" + openssl_includes="$OPENSSL_INCLUDE" fi AC_DEFINE(HAVE_OPENSSL) diff --git a/vio/viosocket.c b/vio/viosocket.c index 898b9a96c11..6f5c4142a45 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -26,8 +26,8 @@ #include #include -#include #include +#include #include #include From 904cad878325be53c185118073ab52b42398194f Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Sat, 19 Jul 2003 10:34:41 +0200 Subject: [PATCH 184/237] typo fixed --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index e0b28874892..69cd1a82108 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -623,7 +623,7 @@ main() FILE *file=fopen("conftestval", "w"); f = (float) ll; fprintf(file,"%g\n",f); - close(file); + fclose(file); exit (0); }], ac_cv_conv_longlong_to_float=`cat conftestval`, ac_cv_conv_longlong_to_float=0, ifelse([$2], , , ac_cv_conv_longlong_to_float=$2))])dnl if test "$ac_cv_conv_longlong_to_float" = "1" -o "$ac_cv_conv_longlong_to_float" = "yes" From cb310f763a4cdb1a1137491df44cd73a057b6d50 Mon Sep 17 00:00:00 2001 From: "hf@deer.(none)" <> Date: Sat, 19 Jul 2003 18:17:29 +0500 Subject: [PATCH 185/237] Fix for #712 with Serg's suggestions --- myisam/mi_locking.c | 2 +- myisam/myisamchk.c | 8 ++------ myisam/myisamdef.h | 1 - sql/ha_myisam.cc | 4 ++-- 4 files changed, 5 insertions(+), 10 deletions(-) diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c index 648c447ae30..22772a3dd2e 100644 --- a/myisam/mi_locking.c +++ b/myisam/mi_locking.c @@ -39,7 +39,7 @@ int mi_lock_database(MI_INFO *info, int lock_type) if (share->options & HA_OPTION_READ_ONLY_DATA || info->lock_type == lock_type) DBUG_RETURN(0); - if (lock_type == MI_TEMPORARY_TABLE) + if (lock_type == F_EXTRA_LCK) { ++share->w_locks; ++share->tot_locks; diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index a7df01e0169..17daab67522 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -878,10 +878,7 @@ static int myisamchk(MI_CHECK *param, my_string filename) param->error_printed=0; goto end2; } - share->w_locks++; /* Mark for writeinfo */ - share->tot_locks++; - info->lock_type= F_EXTRA_LCK; /* Simulate as locked */ - info->tmp_lock_type=lock_type; + mi_lock_database(info, F_EXTRA_LCK); datafile=info->dfile; if (param->testflag & (T_REP_ANY | T_SORT_RECORDS | T_SORT_INDEX)) @@ -1057,8 +1054,7 @@ static int myisamchk(MI_CHECK *param, my_string filename) VOID(lock_file(param, share->kfile,0L,F_UNLCK,"indexfile",filename)); info->update&= ~HA_STATE_CHANGED; } - share->w_locks--; - share->tot_locks--; + mi_lock_database(info, F_UNLCK); end2: if (mi_close(info)) { diff --git a/myisam/myisamdef.h b/myisam/myisamdef.h index 9c2f34990ed..7631b245b9b 100644 --- a/myisam/myisamdef.h +++ b/myisam/myisamdef.h @@ -101,7 +101,6 @@ typedef struct st_mi_state_info #define MI_COLUMNDEF_SIZE (2*3+1) #define MI_BASE_INFO_SIZE (5*8 + 8*4 + 4 + 4*2 + 16) #define MI_INDEX_BLOCK_MARGIN 16 /* Safety margin for .MYI tables */ -#define MI_TEMPORARY_TABLE ((1 & ~F_RDLCK) | (2 & ~F_WRLCK) | (4 & ~F_UNLCK)) typedef struct st_mi_base_info { diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 969fa3232c3..9059ad803f8 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -560,7 +560,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize) // Don't lock tables if we have used LOCK TABLE if (!thd->locked_tables && - mi_lock_database(file, table->tmp_table ? MI_TEMPORARY_TABLE : F_WRLCK)) + mi_lock_database(file, table->tmp_table ? F_EXTRA_LCK : F_WRLCK)) { mi_check_print_error(¶m,ER(ER_CANT_LOCK),my_errno); DBUG_RETURN(HA_ADMIN_FAILED); @@ -1002,7 +1002,7 @@ int ha_myisam::external_lock(THD *thd, int lock_type) { return mi_lock_database(file, !table->tmp_table ? lock_type : ((lock_type == F_UNLCK) ? - F_UNLCK : MI_TEMPORARY_TABLE)); + F_UNLCK : F_EXTRA_LCK)); } From 716e91eecb157dc48f17a48ef7258c465798d4c8 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 21 Jul 2003 13:46:57 +0200 Subject: [PATCH 186/237] Bug #473 - GRANT ... TO ''@... was requiring FLUSH PRIVILEGES to work --- sql/sql_acl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d773aa5bc71..755a72bec32 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -725,7 +725,7 @@ static void acl_insert_user(const char *user, const char *host, ulong privileges) { ACL_USER acl_user; - acl_user.user=strdup_root(&mem,user); + acl_user.user=*user ? strdup_root(&mem,user) : 0; update_hostname(&acl_user.host,strdup_root(&mem,host)); acl_user.password=0; acl_user.access=privileges; From 7a646f305c2259b812588a6131de50a57cf5d083 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 21 Jul 2003 22:21:07 +0200 Subject: [PATCH 187/237] myisamchk --sort-records crash on compressed tables fixed. --- myisam/myisamchk.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 17daab67522..882f868e326 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -1408,6 +1408,12 @@ static int mi_sort_records(MI_CHECK *param, param->error_printed=0; DBUG_RETURN(-1); } + if (share->data_file_type == COMPRESSED_RECORD) + { + mi_check_print_error(param,"Can't sort read-only table '%s'", name); + param->error_printed=0; + DBUG_RETURN(-1); + } if (!(param->testflag & T_SILENT)) { printf("- Sorting records for MyISAM-table '%s'\n",name); From 8e96f029831fdefa4b6f2fd121cdf8609dd85b3a Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 22 Jul 2003 02:44:55 +0300 Subject: [PATCH 188/237] btr0cur.c: Fix bug reported by Dyego Souza do Carmo: if a row becomes too long, > 8000 bytes, in an update, then InnoDB simply removes the clustered index record and does not report of table handler error 139 --- innobase/btr/btr0cur.c | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index 8402993e971..c0fc9566c80 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -1784,6 +1784,28 @@ btr_cur_pessimistic_update( trx->id); } + /* We have to set appropriate extern storage bits in the new + record to be inserted: we have to remember which fields were such */ + + ext_vect = mem_heap_alloc(heap, sizeof(ulint) * rec_get_n_fields(rec)); + n_ext_vect = btr_push_update_extern_fields(ext_vect, rec, update); + + if ((rec_get_converted_size(new_entry) >= + page_get_free_space_of_empty() / 2) + || (rec_get_converted_size(new_entry) >= REC_MAX_DATA_SIZE)) { + + big_rec_vec = dtuple_convert_big_rec(index, new_entry, + ext_vect, n_ext_vect); + if (big_rec_vec == NULL) { + + mem_heap_free(heap); + + err = DB_TOO_BIG_RECORD; + + goto return_after_reservations; + } + } + page_cursor = btr_cur_get_page_cur(cursor); /* Store state of explicit locks on rec on the page infimum record, @@ -1813,30 +1835,10 @@ btr_cur_pessimistic_update( TRUE, mtr); } - /* We have to set appropriate extern storage bits in the new - record to be inserted: we have to remember which fields were such */ - - ext_vect = mem_heap_alloc(heap, sizeof(ulint) * rec_get_n_fields(rec)); - n_ext_vect = btr_push_update_extern_fields(ext_vect, rec, update); - page_cur_delete_rec(page_cursor, mtr); page_cur_move_to_prev(page_cursor); - if ((rec_get_converted_size(new_entry) >= - page_get_free_space_of_empty() / 2) - || (rec_get_converted_size(new_entry) >= REC_MAX_DATA_SIZE)) { - - big_rec_vec = dtuple_convert_big_rec(index, new_entry, - ext_vect, n_ext_vect); - if (big_rec_vec == NULL) { - - mem_heap_free(heap); - - goto return_after_reservations; - } - } - rec = btr_cur_insert_if_possible(cursor, new_entry, &dummy_reorganized, mtr); ut_a(rec || optim_err != DB_UNDERFLOW); From 52706fd316b1ae249b190f95d08de192d442dd3c Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 22 Jul 2003 03:23:02 +0300 Subject: [PATCH 189/237] btr0cur.c: Fix an error in the previous push --- innobase/btr/btr0cur.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index c0fc9566c80..8c9c84b103d 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -1784,6 +1784,20 @@ btr_cur_pessimistic_update( trx->id); } + if (flags & BTR_NO_UNDO_LOG_FLAG) { + /* We are in a transaction rollback undoing a row + update: we must free possible externally stored fields + which got new values in the update, if they are not + inherited values. They can be inherited if we have + updated the primary key to another value, and then + update it back again. */ + + ut_a(big_rec_vec == NULL); + + btr_rec_free_updated_extern_fields(index, rec, update, + TRUE, mtr); + } + /* We have to set appropriate extern storage bits in the new record to be inserted: we have to remember which fields were such */ @@ -1821,20 +1835,6 @@ btr_cur_pessimistic_update( btr_search_update_hash_on_delete(cursor); - if (flags & BTR_NO_UNDO_LOG_FLAG) { - /* We are in a transaction rollback undoing a row - update: we must free possible externally stored fields - which got new values in the update, if they are not - inherited values. They can be inherited if we have - updated the primary key to another value, and then - update it back again. */ - - ut_a(big_rec_vec == NULL); - - btr_rec_free_updated_extern_fields(index, rec, update, - TRUE, mtr); - } - page_cur_delete_rec(page_cursor, mtr); page_cur_move_to_prev(page_cursor); From 3711f4e9858804f6a952da951df7724e4f13684b Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 22 Jul 2003 10:14:43 +0300 Subject: [PATCH 190/237] btr0cur.c: Fix bug: if there was a 'record too long' error in an insert, InnoDB forgot to free reserved file space extents; they were only freed in mysqld restart --- innobase/btr/btr0cur.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index 8c9c84b103d..29a8fd44b9e 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -1107,6 +1107,10 @@ btr_cur_pessimistic_insert( if (big_rec_vec == NULL) { + if (n_extents > 0) { + fil_space_release_free_extents(index->space, + n_extents); + } return(DB_TOO_BIG_RECORD); } } From 60c914302d1f9265ba1a0e0ba2f921887b70fa7e Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Tue, 22 Jul 2003 09:45:53 +0200 Subject: [PATCH 191/237] - tagged ChangeSet 1.1527.1.3 as "mysql-4.0.14" - bumped up version number in configure.in to 4.0.15 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 38847b5217e..64d291dccf7 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.14) +AM_INIT_AUTOMAKE(mysql, 4.0.15) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From 5603456e4f2467c808b1afc60064acd023732bb3 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Tue, 22 Jul 2003 15:04:37 +0500 Subject: [PATCH 192/237] Bug #554: Support for --with-openssl[=DIR] Here is fix for bug 554. Added configure options --with-openssl-includes[=DIR] and --with-openssl-libs[=DIR] --- acinclude.m4 | 55 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 13 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 3bee4e7a874..cc38b271ee6 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -709,20 +709,37 @@ AC_DEFUN(MYSQL_CHECK_VIO, [ ]) AC_DEFUN(MYSQL_FIND_OPENSSL, [ - for d in /usr/ssl/include /usr/local/ssl/include /usr/include \ + incs="$1" + libs="$2" + case "$incs---$libs" in + default---default ) + for d in /usr/ssl/include /usr/local/ssl/include /usr/include \ /usr/include/ssl /opt/ssl/include /opt/openssl/include \ /usr/local/ssl/include /usr/local/include ; do - if test -f $d/openssl/ssl.h ; then - OPENSSL_INCLUDE=-I$d - fi - done + if test -f $d/openssl/ssl.h ; then + OPENSSL_INCLUDE=-I$d + fi + done - for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \ + for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \ /usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib /usr/local/lib/ ; do - if test -f $d/libssl.a ; then - OPENSSL_LIB=$d - fi - done + if test -f $d/libssl.a ; then + OPENSSL_LIB=$d + fi + done + ;; + default---* | *---default | yes---* | *---yes ) + AC_MSG_ERROR([if either 'includes' or 'libs' is specified, both must be specified]) + ;; + * ) + if test -f $incs/openssl/ssl.h ; then + OPENSSL_INCLUDE=-I$incs + fi + if test -f $libs/libssl.a ; then + OPENSSL_LIB=$libs + fi + ;; + esac # On RedHat 9 we need kerberos to compile openssl for d in /usr/kerberos/include @@ -752,11 +769,23 @@ AC_MSG_CHECKING(for OpenSSL) [openssl="$withval"], [openssl=no]) - openssl_libs="" - openssl_includes="" + AC_ARG_WITH([openssl-includes], + [ + --with-openssl-includes=DIR + Find OpenSSL headers in DIR], + [openssl_includes="$withval"], + [openssl_includes=default]) + + AC_ARG_WITH([openssl-libs], + [ + --with-openssl-libs=DIR + Find OpenSSL libraries in DIR], + [openssl_libs="$withval"], + [openssl_libs=default]) + if test "$openssl" = "yes" then - MYSQL_FIND_OPENSSL + MYSQL_FIND_OPENSSL([$openssl_includes], [$openssl_libs]) #force VIO use vio_dir="vio" vio_libs="../vio/libvio.la" From 4ddbb817d545d0650934cbe5e0e5df28bfb87ff7 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Tue, 22 Jul 2003 19:56:52 +0500 Subject: [PATCH 193/237] Bug #554: Support for --with-openssl[=DIR] --- acinclude.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index cc38b271ee6..746ea80d4fb 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -728,7 +728,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ fi done ;; - default---* | *---default | yes---* | *---yes ) + default---* | *---default ) AC_MSG_ERROR([if either 'includes' or 'libs' is specified, both must be specified]) ;; * ) From 06623670c3a6ac84ff7a082251bc99bdeb40c565 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Wed, 23 Jul 2003 16:13:07 +0200 Subject: [PATCH 194/237] --with-openssl-includes/libraries --- acinclude.m4 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 746ea80d4fb..6ca600d29f3 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -712,7 +712,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ incs="$1" libs="$2" case "$incs---$libs" in - default---default ) + ---) for d in /usr/ssl/include /usr/local/ssl/include /usr/include \ /usr/include/ssl /opt/ssl/include /opt/openssl/include \ /usr/local/ssl/include /usr/local/include ; do @@ -728,7 +728,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ fi done ;; - default---* | *---default ) + ---* | *---) AC_MSG_ERROR([if either 'includes' or 'libs' is specified, both must be specified]) ;; * ) @@ -774,14 +774,14 @@ AC_MSG_CHECKING(for OpenSSL) --with-openssl-includes=DIR Find OpenSSL headers in DIR], [openssl_includes="$withval"], - [openssl_includes=default]) + [openssl_includes=""]) AC_ARG_WITH([openssl-libs], [ --with-openssl-libs=DIR Find OpenSSL libraries in DIR], [openssl_libs="$withval"], - [openssl_libs=default]) + [openssl_libs=""]) if test "$openssl" = "yes" then From 33c47c7eadbb72bb680ff1a7df9302030e14e882 Mon Sep 17 00:00:00 2001 From: "miguel@hegel.local" <> Date: Wed, 23 Jul 2003 21:57:44 -0400 Subject: [PATCH 195/237] Fix for service issue with paths having spaces (bug #687) --- include/my_sys.h | 1 + mysys/mf_format.c | 8 ++++++++ sql/mysqld.cc | 7 +++++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 7f8b8a80a1c..acce118c7b8 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -100,6 +100,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_RETURN_REAL_PATH 32 /* return full path for file */ #define MY_SAFE_PATH 64 /* Return NULL if too long path */ #define MY_RELATIVE_PATH 128 /* name is relative to 'dir' */ +#define MY_QUOTE_SPACES 256 /* quote when the path has spaces */ /* My seek flags */ #define MY_SEEK_SET 0 diff --git a/mysys/mf_format.c b/mysys/mf_format.c index ab1904da162..36d3908d310 100644 --- a/mysys/mf_format.c +++ b/mysys/mf_format.c @@ -111,6 +111,14 @@ my_string fn_format(my_string to, const char *name, const char *dir, strmov(buff,to); (void) my_readlink(to, buff, MYF(0)); } + if ( flag & MY_QUOTE_SPACES) + if ( strchr(to, ' ')) + { + char tmp_buff[FN_REFLEN]; + tmp_buff[0]='"'; + strxmov(tmp_buff+1,to,"\"",NullS); + strmov(to,tmp_buff); + } DBUG_RETURN (to); } /* fn_format */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9b8d12e845d..cbd8ebd350b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2559,7 +2559,8 @@ int main(int argc, char **argv) { char file_path[FN_REFLEN]; my_path(file_path, argv[0], ""); /* Find name in path */ - fn_format(file_path,argv[0],file_path,"",1+4+16); /* Force full path */ + fn_format(file_path,argv[0],file_path,"",MY_REPLACE_DIR+ + MY_UNPACK_FILENAME+MY_RESOLVE_SYMLINKS+MY_QUOTE_SPACES); if (argc == 2) { @@ -2605,8 +2606,10 @@ int main(int argc, char **argv) mysqld --install-manual mysqldopt --defaults-file=c:\miguel\my.ini */ uint length=strlen(file_path); + char tmp_path[FN_REFLEN]; + fn_format(tmp_path,argv[3],tmp_path,"",MY_QUOTE_SPACES); *strxnmov(file_path + length, sizeof(file_path)-length-2, " ", - argv[3], " ", argv[2], NullS)= '\0'; + tmp_path, " ", argv[2], NullS)= '\0'; if (!default_service_handling(argv, argv[2], argv[2], file_path)) return 0; } From df3b31f3c496febf104e476720b1fe4ef9696b4e Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Thu, 24 Jul 2003 22:25:36 +0200 Subject: [PATCH 196/237] WL#1036 (print the db in slave error messages). I extended the task to cleaning error messages, making them look nicer, and making the output of SHOW SLAVE STATUS (column Last_error) be as complete as what's printed on the .err file; previously we would have, for a failure of a replicated LOAD DATA INFILE: - in the .err, 2 lines: "duplicate entry 2708 for key 1" "failed loading SQL_LOAD-5-2-2.info" - and in SHOW SLAVE STATUS, only: "failed loading SQL_LOAD-5-2-2.info". Now SHOW SLAVE STATUS will contain the concatenation of the 2 messages. --- sql/log_event.cc | 111 ++++++++++++++++++++++++++++++----------------- sql/slave.cc | 55 ++++++++++++++++++----- sql/slave.h | 3 +- 3 files changed, 117 insertions(+), 52 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index a6d2abbf894..96bcf0a2779 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1753,7 +1753,7 @@ void Unknown_log_event::print(FILE* file, bool short_form, char* last_db) #ifndef MYSQL_CLIENT int Query_log_event::exec_event(struct st_relay_log_info* rli) { - int expected_error,actual_error = 0; + int expected_error, actual_error= 0; init_sql_alloc(&thd->mem_root, 8192,0); thd->db = rewrite_db((char*)db); @@ -1801,19 +1801,30 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) else if (!strcmp(thd->query,"COMMIT")) rli->inside_transaction=0; + /* + If we expected a non-zero error code, and we don't get the same error + code, and none of them should be ignored. + */ if ((expected_error != (actual_error = thd->net.last_errno)) && expected_error && !ignored_error_code(actual_error) && !ignored_error_code(expected_error)) { - const char* errmsg = "Slave: did not get the expected error\ - running query from master - expected: '%s' (%d), got '%s' (%d)"; - sql_print_error(errmsg, ER_SAFE(expected_error), - expected_error, - actual_error ? thd->net.last_error: "no error", - actual_error); - thd->query_error = 1; + slave_print_error(rli, 0, + "Query '%s' did not get the same error as the query \ +got on master - got on master: '%s' (%d), got on slave: '%s' (%d) \ +(default database was '%s')", + query, + ER_SAFE(expected_error), + expected_error, + actual_error ? thd->net.last_error: "no error", + actual_error, + print_slave_db_safe((char*)db)); + thd->query_error= 1; } + /* + If we get the same error code as expected, or they should be ignored. + */ else if (expected_error == actual_error || ignored_error_code(actual_error)) { @@ -1821,37 +1832,38 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) *rli->last_slave_error = 0; rli->last_slave_errno = 0; } - } - else - { - // master could be inconsistent, abort and tell DBA to check/fix it - VOID(pthread_mutex_lock(&LOCK_thread_count)); - thd->db = thd->query = 0; - VOID(pthread_mutex_unlock(&LOCK_thread_count)); - thd->variables.convert_set = 0; - close_thread_tables(thd); - free_root(&thd->mem_root,0); - return 1; - } - } - thd->db= 0; // prevent db from being freed + /* + Other cases: mostly we expected no error and get one. + */ + else if (thd->query_error || thd->fatal_error) + { + slave_print_error(rli,actual_error, "Error '%s' on query '%s' \ +(default database was '%s')", + actual_error ? thd->net.last_error : + "unexpected success or fatal error", query, + print_slave_db_safe((char*)db)); + thd->query_error= 1; + } + } + /* + End of sanity check. If the test was wrong, the query got a really bad + error on the master, which could be inconsistent, abort and tell DBA to + check/fix it. check_expected_error() already printed the message to + stderr and rli, and set thd->query_error to 1. + */ + } /* End of if (db_ok(... */ + +end: + VOID(pthread_mutex_lock(&LOCK_thread_count)); + thd->db= 0; // prevent db from being freed thd->query= 0; // just to be sure VOID(pthread_mutex_unlock(&LOCK_thread_count)); // assume no convert for next query unless set explictly thd->variables.convert_set = 0; - close_thread_tables(thd); - - if (thd->query_error || thd->fatal_error) - { - slave_print_error(rli,actual_error, "error '%s' on query '%s'", - actual_error ? thd->net.last_error : - "unexpected success or fatal error", query); - free_root(&thd->mem_root,0); - return 1; - } + close_thread_tables(thd); free_root(&thd->mem_root,0); - return Log_event::exec_event(rli); + return (thd->query_error ? thd->query_error : Log_event::exec_event(rli)); } /* @@ -1972,8 +1984,11 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, event in the master log */ sql_print_error("Slave: load data infile at position %s in log \ -'%s' produced %d warning(s)", llstr(log_pos,llbuff), RPL_LOG_NAME, - thd->cuted_fields ); +'%s' produced %d warning(s) (loaded table was '%s', database was '%s')", + llstr(log_pos,llbuff), RPL_LOG_NAME, + thd->cuted_fields, + (char*)table_name, + print_slave_db_safe((char*)db)); if (net) net->pkt_nr= thd->net.pkt_nr; } @@ -2005,8 +2020,9 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, err=ER(sql_errno); } slave_print_error(rli,sql_errno, - "Error '%s' running load data infile", - err); + "Error '%s' running load data infile \ +(loaded table was '%s', database was '%s')", + err, (char*)table_name, print_slave_db_safe((char*)db)); free_root(&thd->mem_root,0); return 1; } @@ -2014,7 +2030,10 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, if (thd->fatal_error) { - sql_print_error("Fatal error running LOAD DATA INFILE "); + slave_print_error(rli,ER_UNKNOWN_ERROR, +"Fatal error running \ +LOAD DATA INFILE (loaded table was '%s', database was '%s')", + (char*)table_name, print_slave_db_safe((char*)db)); return 1; } @@ -2311,7 +2330,21 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) */ if (lev->exec_event(0,rli,1)) { - slave_print_error(rli,my_errno, "Failed executing load from '%s'", fname); + /* + We want to indicate the name of the file that could not be loaded + (SQL_LOADxxx). + But as we are here we are sure the error is in rli->last_slave_error and + rli->last_slave_errno (example of error: duplicate entry for key), so we + don't want to overwrite it with the filename. + What we want instead is add the filename to the current error message. + */ + char *tmp= my_strdup(rli->last_slave_error,MYF(MY_WME)); + if (!tmp) + goto err; + slave_print_error(rli,rli->last_slave_errno, /* ok to re-use the error code */ + "%s. Failed executing load from '%s'", + tmp, fname); + my_free(tmp,MYF(0)); thd->options = save_options; goto err; } diff --git a/sql/slave.cc b/sql/slave.cc index 6ace446a341..b4fa11f456e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -74,7 +74,6 @@ static int request_table_dump(MYSQL* mysql, const char* db, const char* table); static int create_table_from_dump(THD* thd, NET* net, const char* db, const char* table_name); static int check_master_version(MYSQL* mysql, MASTER_INFO* mi); -char* rewrite_db(char* db); /* @@ -290,8 +289,6 @@ err: if (need_data_lock) pthread_mutex_unlock(&rli->data_lock); - /* Isn't this strange: if !need_data_lock, we broadcast with no lock ?? */ - pthread_mutex_unlock(log_lock); DBUG_RETURN ((*errmsg) ? 1 : 0); } @@ -362,7 +359,10 @@ int purge_relay_logs(RELAY_LOG_INFO* rli, THD *thd, bool just_reset, rli->pending= 0; if (!rli->inited) + { + DBUG_PRINT("info", ("rli->inited == 0")); DBUG_RETURN(0); + } DBUG_ASSERT(rli->slave_running == 0); DBUG_ASSERT(rli->mi->slave_running == 0); @@ -828,6 +828,21 @@ static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli) return rli->abort_slave || abort_loop || thd->killed; } +/* + Writes an error message to rli->last_slave_error and rli->last_slave_errno + (which will be displayed by SHOW SLAVE STATUS), and prints it to stderr. + + SYNOPSIS + slave_print_error() + rli + err_code The error code + msg The error message (usually related to the error code, but can + contain more information). + ... (this is printf-like format, with % symbols in msg) + + RETURN VALUES + void + */ void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...) { @@ -835,9 +850,16 @@ void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...) va_start(args,msg); my_vsnprintf(rli->last_slave_error, sizeof(rli->last_slave_error), msg, args); - sql_print_error("Slave: %s, error_code=%d", rli->last_slave_error, - err_code); rli->last_slave_errno = err_code; + /* If the error string ends with '.', do not add a ',' it would be ugly */ + if (rli->last_slave_error[0] && + (rli->last_slave_error[strlen(rli->last_slave_error)-1] == '.')) + sql_print_error("Slave: %s Error_code=%d", rli->last_slave_error, + err_code); + else + sql_print_error("Slave: %s, error_code=%d", rli->last_slave_error, + err_code); + } @@ -865,6 +887,16 @@ char* rewrite_db(char* db) return db; } +/* + From other comments and tests in code, it looks like + sometimes Query_log_event and Load_log_event can have db==0 + (see rewrite_db() above for example) + (cases where this happens are unclear; it may be when the master is 3.23). +*/ +char* print_slave_db_safe(char* db) +{ + return (db ? rewrite_db(db) : (char*) ""); +} /* Checks whether a db matches some do_db and ignore_db rules @@ -1282,7 +1314,7 @@ file '%s')", fname); &msg)) { sql_print_error("Failed to open the relay log (relay_log_name='FIRST', \ -relay_log_pos=4"); +relay_log_pos=4)"); goto err; } rli->master_log_name[0]= 0; @@ -1346,7 +1378,7 @@ file '%s')", fname); { char llbuf[22]; sql_print_error("Failed to open the relay log (relay_log_name='%s', \ -relay_log_pos=%s", rli->relay_log_name, llstr(rli->relay_log_pos, llbuf)); +relay_log_pos=%s)", rli->relay_log_name, llstr(rli->relay_log_pos, llbuf)); goto err; } } @@ -2142,14 +2174,13 @@ int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int expected_error) case ER_NET_ERROR_ON_WRITE: case ER_SERVER_SHUTDOWN: case ER_NEW_ABORTING_CONNECTION: - my_snprintf(rli->last_slave_error, sizeof(rli->last_slave_error), - "Slave: query '%s' partially completed on the master \ + slave_print_error(rli,expected_error, + "query '%s' partially completed on the master \ and was aborted. There is a chance that your master is inconsistent at this \ point. If you are sure that your master is ok, run this query manually on the\ slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;\ - SLAVE START;", thd->query); - rli->last_slave_errno = expected_error; - sql_print_error("%s",rli->last_slave_error); + SLAVE START; .", thd->query); + thd->query_error= 1; return 1; default: return 0; diff --git a/sql/slave.h b/sql/slave.h index 842ddca75f4..d1fd54d3c04 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -383,9 +383,10 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec); void init_table_rule_hash(HASH* h, bool* h_inited); void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited); char* rewrite_db(char* db); +char* print_slave_db_safe(char* db); int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code); void skip_load_data_infile(NET* net); -void slave_print_error(RELAY_LOG_INFO* rli,int err_code, const char* msg, ...); +void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...); void end_slave(); /* clean up */ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, From aba7647fd814cf3d9171e7f742d5e72266cc54ec Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Thu, 24 Jul 2003 22:29:09 +0200 Subject: [PATCH 197/237] Fix for BUG#858 "CHANGE MASTER forgets to update relay-log.info"; just a flush_relay_log_info() at the end of CHANGE MASTER (there was already flush_master_info()). --- sql/sql_repl.cc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 13b22d6a221..faa18b146bb 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -878,9 +878,14 @@ int change_master(THD* thd, MASTER_INFO* mi) and we have the hold on the run locks which will keep all threads that could possibly modify the data structures from running */ + + /* + If the user specified host or port without binlog or position, + reset binlog's name to FIRST and position to 4. + */ + if ((lex_mi->host || lex_mi->port) && !lex_mi->log_file_name && !lex_mi->pos) { - // if we change host or port, we must reset the postion mi->master_log_name[0] = 0; mi->master_log_pos= BIN_LOG_HEADER_SIZE; mi->rli.pending = 0; @@ -950,15 +955,24 @@ int change_master(THD* thd, MASTER_INFO* mi) DBUG_RETURN(1); } } - mi->rli.master_log_pos = mi->master_log_pos; DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); + /* If changing RELAY_LOG_FILE or RELAY_LOG_POS, this will be nonsense: */ + mi->rli.master_log_pos = mi->master_log_pos; strmake(mi->rli.master_log_name,mi->master_log_name, sizeof(mi->rli.master_log_name)-1); if (!mi->rli.master_log_name[0]) // uninitialized case mi->rli.master_log_pos=0; pthread_mutex_lock(&mi->rli.data_lock); - mi->rli.abort_pos_wait++; + mi->rli.abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */ + /* + If we don't write new coordinates to disk now, then old will remain in + relay-log.info until START SLAVE is issued; but if mysqld is shutdown + before START SLAVE, then old will remain in relay-log.info, and will be the + in-memory value at restart (thus causing errors, as the old relay log does + not exist anymore). + */ + flush_relay_log_info(&mi->rli); pthread_cond_broadcast(&mi->data_cond); pthread_mutex_unlock(&mi->rli.data_lock); From 1dfaccb0164336aa004ea373a67bc8735a290b80 Mon Sep 17 00:00:00 2001 From: "gluh@gluh.mysql.r18.ru" <> Date: Fri, 25 Jul 2003 09:25:50 +0500 Subject: [PATCH 198/237] Fix: remove compile warnings on RH(with openssl) --- acinclude.m4 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/acinclude.m4 b/acinclude.m4 index 6ca600d29f3..b558e952543 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -745,7 +745,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ for d in /usr/kerberos/include do if test -f $d/krb5.h ; then - OPENSSL_INCLUDE="$OPENSSL_INCLUDE -I$d" + OPENSSL_KERBEROS_INCLUDE="$d" fi done @@ -794,10 +794,15 @@ AC_MSG_CHECKING(for OpenSSL) openssl_libs="-L$OPENSSL_LIB -lssl -lcrypto" # Don't set openssl_includes to /usr/include as this gives us a lot of # compiler warnings when using gcc 3.x + openssl_includes="" if test "$OPENSSL_INCLUDE" != "-I/usr/include" then openssl_includes="$OPENSSL_INCLUDE" fi + if test "$OPENSSL_KERBEROS_INCLUDE" + then + openssl_includes="$openssl_includes -I$OPENSSL_KERBEROS_INCLUDE" + fi AC_DEFINE(HAVE_OPENSSL) # openssl-devel-0.9.6 requires dlopen() and we can't link staticly From 4e22494ebf8847ee4842159534b1f14d895feb2f Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Fri, 25 Jul 2003 14:32:03 +0200 Subject: [PATCH 199/237] outer join, impossible on condition, where, and usable key for range bug#926 --- mysql-test/r/select.result | 20 ++++++++++++++++++++ mysql-test/t/select.test | 20 ++++++++++++++++++++ sql/sql_select.cc | 4 ---- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 811c396ea67..bde527b9b44 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -3508,3 +3508,23 @@ aa id t2_id id 5 8303 2520 2520 6 8304 2521 2521 drop table t1,t2; +create table t1 (id1 int NOT NULL); +create table t2 (id2 int NOT NULL); +create table t3 (id3 int NOT NULL); +create table t4 (id4 int NOT NULL, id44 int NOT NULL, KEY (id4)); +insert into t1 values (1); +insert into t1 values (2); +insert into t2 values (1); +insert into t4 values (1,1); +explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 +left join t4 on id3 = id4 where id2 = 1 or id4 = 1; +table type possible_keys key key_len ref rows Extra +t3 system NULL NULL NULL NULL 0 const row not found +t1 ALL NULL NULL NULL NULL 2 +t2 ALL NULL NULL NULL NULL 1 +t4 ALL id4 NULL NULL NULL 1 Using where +select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 +left join t4 on id3 = id4 where id2 = 1 or id4 = 1; +id1 id2 id3 id4 id44 +1 1 NULL NULL NULL +drop table t1,t2,t3,t4; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index c2e451ea7f3..9884c88b420 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1832,3 +1832,23 @@ INSERT INTO t2 VALUES (2517), (2518), (2519), (2520), (2521), (2522); select * from t1, t2 WHERE t1.t2_id = t2.id and t1.t2_id > 0 order by t1.id LIMIT 0, 5; drop table t1,t2; +# +# outer join, impossible on condition, where, and usable key for range +# +create table t1 (id1 int NOT NULL); +create table t2 (id2 int NOT NULL); +create table t3 (id3 int NOT NULL); +create table t4 (id4 int NOT NULL, id44 int NOT NULL, KEY (id4)); + +insert into t1 values (1); +insert into t1 values (2); +insert into t2 values (1); +insert into t4 values (1,1); + +explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 +left join t4 on id3 = id4 where id2 = 1 or id4 = 1; +select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 +left join t4 on id3 = id4 where id2 = 1 or id4 = 1; + +drop table t1,t2,t3,t4; + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4008bf75f01..6675a310464 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2641,9 +2641,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) join->thd->select_limit < join->best_positions[i].records_read && !(join->select_options & OPTION_FOUND_ROWS))) { - /* Join with outer join condition */ - COND *orig_cond=sel->cond; - sel->cond=and_conds(sel->cond,tab->on_expr); if (sel->test_quick_select(tab->keys, used_tables & ~ current_map, (join->select_options & @@ -2651,7 +2648,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) HA_POS_ERROR : join->thd->select_limit)) < 0) DBUG_RETURN(1); // Impossible range - sel->cond=orig_cond; /* Fix for EXPLAIN */ if (sel->quick) join->best_positions[i].records_read= sel->quick->records; From c1b62170a7afd62fc20b9d22da5592868abf255f Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Fri, 25 Jul 2003 22:26:39 +0300 Subject: [PATCH 200/237] srv0srv.c, os0file.c, log0recv.h, log0log.h, fil0fil.h, fsp0fsp.c, fil0fil.c: Merge trx0trx.c: Print more info about a trx in SHOW INNODB status; try to find the bug reported by Plaxo buf0buf.c: Check that page log sequence numbers are not in the future log0recv.c, log0log.c: Fixed a bug: if you used big BLOBs, and your log files were relatively small, InnoDB could in a big BLOB operation temporarily write over the log produced AFTER the latest checkpoint. If InnoDB would crash at that moment, then the crash recovery would fail, because InnoDB would not be able to scan the log even up to the latest checkpoint. Starting from this version, InnoDB tries to ensure the latest checkpoint is young enough. If that is not possible, InnoDB prints a warning to the .err log --- innobase/buf/buf0buf.c | 23 ++++++++++++ innobase/fil/fil0fil.c | 28 ++++++++++++++ innobase/fsp/fsp0fsp.c | 46 ++++++++++++++++++++++- innobase/include/fil0fil.h | 8 ++++ innobase/include/log0log.h | 14 +++++++ innobase/include/log0recv.h | 2 + innobase/log/log0log.c | 75 ++++++++++++++++++++++++++++++++----- innobase/log/log0recv.c | 49 ++++++++++++++++++++++-- innobase/os/os0file.c | 1 + innobase/srv/srv0srv.c | 15 +++++++- innobase/trx/trx0trx.c | 7 ++++ 11 files changed, 253 insertions(+), 15 deletions(-) diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index 246a60a61cd..3f2476c715b 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -34,6 +34,7 @@ Created 11/5/1995 Heikki Tuuri #include "ibuf0ibuf.h" #include "dict0dict.h" #include "log0recv.h" +#include "log0log.h" #include "trx0undo.h" #include "srv0srv.h" @@ -273,6 +274,7 @@ buf_page_is_corrupted( ulint old_checksum; ulint checksum_field; ulint old_checksum_field; + dulint current_lsn; if (mach_read_from_4(read_buf + FIL_PAGE_LSN + 4) != mach_read_from_4(read_buf + UNIV_PAGE_SIZE @@ -284,6 +286,27 @@ buf_page_is_corrupted( return(TRUE); } +#ifndef UNIV_HOTBACKUP + if (recv_lsn_checks_on && log_peek_lsn(¤t_lsn)) { + if (ut_dulint_cmp(current_lsn, + mach_read_from_8(read_buf + FIL_PAGE_LSN)) + < 0) { + ut_print_timestamp(stderr); + + fprintf(stderr, +" InnoDB: Error: page %lu log sequence number %lu %lu\n" +"InnoDB: is in the future! Current system log sequence number %lu %lu.\n" +"InnoDB: Your database may be corrupt.\n", + mach_read_from_4(read_buf + FIL_PAGE_OFFSET), + ut_dulint_get_high( + mach_read_from_8(read_buf + FIL_PAGE_LSN)), + ut_dulint_get_low( + mach_read_from_8(read_buf + FIL_PAGE_LSN)), + ut_dulint_get_high(current_lsn), + ut_dulint_get_low(current_lsn)); + } + } +#endif old_checksum = buf_calc_page_old_checksum(read_buf); old_checksum_field = mach_read_from_4(read_buf + UNIV_PAGE_SIZE diff --git a/innobase/fil/fil0fil.c b/innobase/fil/fil0fil.c index a8dc357749c..f55df90846c 100644 --- a/innobase/fil/fil0fil.c +++ b/innobase/fil/fil0fil.c @@ -831,6 +831,34 @@ fil_space_release_free_extents( mutex_exit(&(system->mutex)); } +/*********************************************************************** +Gets the number of reserved extents. If the database is silent, this number +should be zero. */ + +ulint +fil_space_get_n_reserved_extents( +/*=============================*/ + ulint id) /* in: space id */ +{ + fil_space_t* space; + fil_system_t* system = fil_system; + ulint n; + + ut_ad(system); + + mutex_enter(&(system->mutex)); + + HASH_SEARCH(hash, system->spaces, id, space, space->id == id); + + ut_a(space); + + n = space->n_reserved_extents; + + mutex_exit(&(system->mutex)); + + return(n); +} + /************************************************************************ Prepares a file node for i/o. Opens the file if it is closed. Updates the pending i/o's field in the node and the system appropriately. Takes the node diff --git a/innobase/fsp/fsp0fsp.c b/innobase/fsp/fsp0fsp.c index b6941d80e90..20bf4972f64 100644 --- a/innobase/fsp/fsp0fsp.c +++ b/innobase/fsp/fsp0fsp.c @@ -2709,10 +2709,52 @@ fseg_free_page_low( return; } +/* + fprintf(stderr, +"InnoDB: InnoDB is freeing space %lu page %lu,\n" +"InnoDB: which belongs to descr seg %lu %lu\n" +"InnoDB: segment %lu %lu.\n", + space, page, + ut_dulint_get_high( + mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr)), + ut_dulint_get_low( + mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr)), + ut_dulint_get_high( + mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr)), + ut_dulint_get_low( + mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr))); +*/ /* If we get here, the page is in some extent of the segment */ - ut_a(0 == ut_dulint_cmp( + if (0 != ut_dulint_cmp( mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr), - mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr))); + mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr))) { + + ut_sprintf_buf(errbuf, descr, 40); + fprintf(stderr, +"InnoDB: Dump of the tablespace extent descriptor: %s\n", errbuf); + ut_sprintf_buf(errbuf, seg_inode, 40); + fprintf(stderr, +"InnoDB: Dump of the segment inode: %s\n", errbuf); + + fprintf(stderr, +"InnoDB: Serious error: InnoDB is trying to free space %lu page %lu,\n" +"InnoDB: which does not belong to segment %lu %lu but belongs\n" +"InnoDB: to segment %lu %lu.\n", + space, page, + ut_dulint_get_high( + mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr)), + ut_dulint_get_low( + mtr_read_dulint(descr + XDES_ID, MLOG_8BYTES, mtr)), + ut_dulint_get_high( + mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr)), + ut_dulint_get_low( + mtr_read_dulint(seg_inode + FSEG_ID, MLOG_8BYTES, mtr))); + + fprintf(stderr, +"InnoDB: If the InnoDB recovery crashes here, see section 6.1\n" +"InnoDB: of http://www.innodb.com/ibman.html about forcing recovery.\n"); + ut_a(0); + } not_full_n_used = mtr_read_ulint(seg_inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr); diff --git a/innobase/include/fil0fil.h b/innobase/include/fil0fil.h index 4f78fdb2fd7..ad3149f0b36 100644 --- a/innobase/include/fil0fil.h +++ b/innobase/include/fil0fil.h @@ -386,6 +386,14 @@ fil_space_release_free_extents( /*===========================*/ ulint id, /* in: space id */ ulint n_reserved); /* in: how many one reserved */ +/*********************************************************************** +Gets the number of reserved extents. If the database is silent, this number +should be zero. */ + +ulint +fil_space_get_n_reserved_extents( +/*=============================*/ + ulint id); /* in: space id */ typedef struct fil_space_struct fil_space_t; diff --git a/innobase/include/log0log.h b/innobase/include/log0log.h index e79e914e4f6..24ec28a56e6 100644 --- a/innobase/include/log0log.h +++ b/innobase/include/log0log.h @@ -513,6 +513,15 @@ log_print( /*======*/ char* buf, /* in/out: buffer where to print */ char* buf_end);/* in: buffer end */ +/********************************************************** +Peeks the current lsn. */ + +ibool +log_peek_lsn( +/*=========*/ + /* out: TRUE if success, FALSE if could not get the + log system mutex */ + dulint* lsn); /* out: if returns TRUE, current lsn is here */ /************************************************************************** Refreshes the statistics used to print per-second averages. */ @@ -785,6 +794,11 @@ struct log_struct{ called */ /* Fields involved in checkpoints */ + ulint log_group_capacity; /* capacity of the log group; if + the checkpoint age exceeds this, it is + a serious error because it is possible + we will then overwrite log and spoil + crash recovery */ ulint max_modified_age_async; /* when this recommended value for lsn - buf_pool_get_oldest_modification() diff --git a/innobase/include/log0recv.h b/innobase/include/log0recv.h index 7418e4abf1b..e5a5bc05563 100644 --- a/innobase/include/log0recv.h +++ b/innobase/include/log0recv.h @@ -333,6 +333,8 @@ extern ibool recv_recovery_on; extern ibool recv_no_ibuf_operations; extern ibool recv_needed_recovery; +extern ibool recv_lsn_checks_on; + extern ibool recv_is_making_a_backup; extern ulint recv_max_parsed_page_no; diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index 53ca97baaa0..99827da5bf5 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -33,6 +33,11 @@ log_t* log_sys = NULL; ibool log_do_write = TRUE; ibool log_debug_writes = FALSE; +/* These control how often we print warnings if the last checkpoint is too +old */ +ibool log_has_printed_chkp_warning = FALSE; +time_t log_last_warning_time; + /* Pointer to this variable is used as the i/o-message when we do i/o to an archive */ byte log_archive_io; @@ -299,6 +304,7 @@ log_close(void) dulint oldest_lsn; dulint lsn; log_t* log = log_sys; + ulint checkpoint_age; ut_ad(mutex_own(&(log->mutex))); @@ -322,8 +328,34 @@ log_close(void) log->check_flush_or_checkpoint = TRUE; } - if (ut_dulint_minus(lsn, log->last_checkpoint_lsn) - <= log->max_modified_age_async) { + checkpoint_age = ut_dulint_minus(lsn, log->last_checkpoint_lsn); + + if (checkpoint_age >= log->log_group_capacity) { + /* TODO: split btr_store_big_rec_extern_fields() into small + steps so that we can release all latches in the middle, and + call log_free_check() to ensure we never write over log written + after the latest checkpoint. In principle, we should split all + big_rec operations, but other operations are smaller. */ + + if (!log_has_printed_chkp_warning + || difftime(time(NULL), log_last_warning_time) > 15) { + + log_has_printed_chkp_warning = TRUE; + log_last_warning_time = time(NULL); + + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: ERROR: the age of the last checkpoint is %lu,\n" +"InnoDB: which exceeds the log group capacity %lu.\n" +"InnoDB: If you are using big BLOB or TEXT rows, you must set the\n" +"InnoDB: combined size of log files at least 10 times bigger than the\n" +"InnoDB: largest such row.\n", + checkpoint_age, log->log_group_capacity); + } + } + + if (checkpoint_age <= log->max_modified_age_async) { + goto function_exit; } @@ -332,8 +364,7 @@ log_close(void) if (ut_dulint_is_zero(oldest_lsn) || (ut_dulint_minus(lsn, oldest_lsn) > log->max_modified_age_async) - || (ut_dulint_minus(lsn, log->last_checkpoint_lsn) - > log->max_checkpoint_age_async)) { + || checkpoint_age > log->max_checkpoint_age_async) { log->check_flush_or_checkpoint = TRUE; } @@ -551,7 +582,6 @@ log_calc_max_ages(void) the database server */ { log_group_t* group; - ulint n_threads; ulint margin; ulint free; ibool success = TRUE; @@ -561,8 +591,6 @@ log_calc_max_ages(void) ut_ad(!mutex_own(&(log_sys->mutex))); - n_threads = srv_get_n_threads(); - mutex_enter(&(log_sys->mutex)); group = UT_LIST_GET_FIRST(log_sys->log_groups); @@ -590,12 +618,15 @@ log_calc_max_ages(void) group = UT_LIST_GET_NEXT(log_groups, group); } + /* Add extra safety */ + smallest_capacity = smallest_capacity - smallest_capacity / 10; + /* For each OS thread we must reserve so much free space in the smallest log group that it can accommodate the log entries produced by single query steps: running out of free log space is a serious system error which requires rebooting the database. */ - free = LOG_CHECKPOINT_FREE_PER_THREAD * n_threads + free = LOG_CHECKPOINT_FREE_PER_THREAD * (10 + srv_thread_concurrency) + LOG_CHECKPOINT_EXTRA_FREE; if (free >= smallest_capacity / 2) { success = FALSE; @@ -607,6 +638,10 @@ log_calc_max_ages(void) margin = ut_min(margin, log_sys->adm_checkpoint_interval); + margin = margin - margin / 10; /* Add still some extra safety */ + + log_sys->log_group_capacity = smallest_capacity; + log_sys->max_modified_age_async = margin - margin / LOG_POOL_PREFLUSH_RATIO_ASYNC; log_sys->max_modified_age_sync = margin @@ -626,7 +661,7 @@ failure: if (!success) { fprintf(stderr, - "Error: log file group too small for the number of threads\n"); +"InnoDB: Error: log file group too small for innodb_thread_concurrency\n"); } return(success); @@ -3111,6 +3146,28 @@ log_check_log_recs( return(TRUE); } +/********************************************************** +Peeks the current lsn. */ + +ibool +log_peek_lsn( +/*=========*/ + /* out: TRUE if success, FALSE if could not get the + log system mutex */ + dulint* lsn) /* out: if returns TRUE, current lsn is here */ +{ + if (0 == mutex_enter_nowait(&(log_sys->mutex), (char*)__FILE__, + __LINE__)) { + *lsn = log_sys->lsn; + + mutex_exit(&(log_sys->mutex)); + + return(TRUE); + } + + return(FALSE); +} + /********************************************************** Prints info of the log. */ diff --git a/innobase/log/log0recv.c b/innobase/log/log0recv.c index 8e5fe819afb..9c9ad568d98 100644 --- a/innobase/log/log0recv.c +++ b/innobase/log/log0recv.c @@ -46,6 +46,8 @@ ibool recv_recovery_from_backup_on = FALSE; ibool recv_needed_recovery = FALSE; +ibool recv_lsn_checks_on = FALSE; + /* If the following is TRUE, the buffer pool file pages must be invalidated after recovery and no ibuf operations are allowed; this becomes TRUE if the log record hash table becomes too full, and log records must be merged @@ -71,6 +73,12 @@ ulint recv_previous_parsed_rec_is_multi = 0; ulint recv_max_parsed_page_no = 0; +/* The maximum lsn we see for a page during the recovery process. If this +is bigger than the lsn we are able to scan up to, that is an indication that +the recovery failed and the database may be corrupt. */ + +dulint recv_max_page_lsn; + /************************************************************ Creates the recovery system. */ @@ -132,6 +140,8 @@ recv_sys_init( OS_FILE_LOG_BLOCK_SIZE); recv_sys->found_corrupt_log = FALSE; + recv_max_page_lsn = ut_dulint_zero; + mutex_exit(&(recv_sys->mutex)); } @@ -1124,6 +1134,10 @@ recv_recover_page( mutex_enter(&(recv_sys->mutex)); + if (ut_dulint_cmp(recv_max_page_lsn, page_lsn) < 0) { + recv_max_page_lsn = page_lsn; + } + recv_addr->state = RECV_PROCESSED; ut_a(recv_sys->n_addrs); @@ -2192,9 +2206,12 @@ recv_scan_log_recs( while (log_block < buf + len && !finished) { no = log_block_get_hdr_no(log_block); +/* + fprintf(stderr, "Log block header no %lu\n", no); - /* fprintf(stderr, "Log block header no %lu\n", no); */ - + fprintf(stderr, "Scanned lsn no %lu\n", + log_block_convert_lsn_to_no(scanned_lsn)); +*/ if (no != log_block_convert_lsn_to_no(scanned_lsn) || !log_block_checksum_is_ok_or_old_format(log_block)) { @@ -2586,7 +2603,6 @@ recv_recovery_from_checkpoint_start( recv_group_scan_log_recs(group, &contiguous_lsn, &group_scanned_lsn); - group->scanned_lsn = group_scanned_lsn; if (ut_dulint_cmp(old_scanned_lsn, group_scanned_lsn) < 0) { @@ -2603,6 +2619,31 @@ recv_recovery_from_checkpoint_start( group = UT_LIST_GET_NEXT(log_groups, group); } + /* We currently have only one log group */ + if (ut_dulint_cmp(group_scanned_lsn, checkpoint_lsn) < 0) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: ERROR: We were only able to scan the log up to\n" +"InnoDB: %lu %lu, but a checkpoint was at %lu %lu.\n" +"InnoDB: It is possible that the database is now corrupt!\n", + ut_dulint_get_high(group_scanned_lsn), + ut_dulint_get_low(group_scanned_lsn), + ut_dulint_get_high(checkpoint_lsn), + ut_dulint_get_low(checkpoint_lsn)); + } + + if (ut_dulint_cmp(group_scanned_lsn, recv_max_page_lsn) < 0) { + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: ERROR: We were only able to scan the log up to %lu %lu\n" +"InnoDB: but a database page a had an lsn %lu %lu. It is possible that the\n" +"InnoDB: database is now corrupt!\n", + ut_dulint_get_high(group_scanned_lsn), + ut_dulint_get_low(group_scanned_lsn), + ut_dulint_get_high(recv_max_page_lsn), + ut_dulint_get_low(recv_max_page_lsn)); + } + if (ut_dulint_cmp(recv_sys->recovered_lsn, checkpoint_lsn) < 0) { mutex_exit(&(log_sys->mutex)); @@ -2656,6 +2697,8 @@ recv_recovery_from_checkpoint_start( sync_order_checks_on = FALSE; + recv_lsn_checks_on = TRUE; + /* The database is now ready to start almost normal processing of user transactions: transaction rollbacks and the application of the log records in the hash table can be run in background. */ diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index a9a64ae7864..7936b06c24d 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -1030,6 +1030,7 @@ os_file_flush( #ifdef HAVE_FDATASYNC ret = fdatasync(file); #else +/* printf("Flushing to file %lu\n", (ulint)file); */ ret = fsync(file); #endif os_n_fsyncs++; diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index f81b2d0a60e..f31d275eff0 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -1798,8 +1798,12 @@ retry: os_fast_mutex_unlock(&srv_conc_mutex); + trx->op_info = (char*)"sleeping before joining InnoDB queue"; + os_thread_sleep(50000); + trx->op_info = (char*)""; + os_fast_mutex_lock(&srv_conc_mutex); srv_conc_n_waiting_threads--; @@ -2299,6 +2303,7 @@ srv_sprintf_innodb_monitor( char* buf_end = buf + len - 2000; double time_elapsed; time_t current_time; + ulint n_reserved; mutex_enter(&srv_innodb_monitor_mutex); @@ -2414,8 +2419,16 @@ srv_sprintf_innodb_monitor( "ROW OPERATIONS\n" "--------------\n"); buf += sprintf(buf, - "%ld queries inside InnoDB, %ld queries in queue\n", + "%ld queries inside InnoDB, %lu queries in queue\n", srv_conc_n_threads, srv_conc_n_waiting_threads); + + n_reserved = fil_space_get_n_reserved_extents(0); + if (n_reserved > 0) { + buf += sprintf(buf, + "%lu tablespace extents now reserved for B-tree split operations\n", + n_reserved); + } + #ifdef UNIV_LINUX buf += sprintf(buf, "Main thread process no. %lu, id %lu, state: %s\n", diff --git a/innobase/trx/trx0trx.c b/innobase/trx/trx0trx.c index e8d6c093680..47c39290b15 100644 --- a/innobase/trx/trx0trx.c +++ b/innobase/trx/trx0trx.c @@ -1624,6 +1624,13 @@ trx_print( } buf += sprintf(buf, "\n"); + + if (trx->n_mysql_tables_in_use > 0 || trx->mysql_n_tables_locked > 0) { + + buf += sprintf(buf, "mysql tables in use %lu, locked %lu\n", + trx->n_mysql_tables_in_use, + trx->mysql_n_tables_locked); + } start_of_line = buf; From 34352d0c216536e0dea1b3df4ce7de40f61788a6 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 26 Jul 2003 17:59:05 +0200 Subject: [PATCH 201/237] Make rpl_insert_id.test use InnoDB, and added foreign keys to the table, so that it really tests replication of SET FOREIGN_KEY_CHECKS (previously it used MyISAM). --- mysql-test/r/rpl_insert_id.result | 4 ++-- mysql-test/t/rpl_insert_id.test | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/rpl_insert_id.result b/mysql-test/r/rpl_insert_id.result index 0065d83f169..889e7891770 100644 --- a/mysql-test/r/rpl_insert_id.result +++ b/mysql-test/r/rpl_insert_id.result @@ -21,8 +21,8 @@ b c 1 4 drop table t1; drop table t2; -create table t1(a int auto_increment, key(a)); -create table t2(b int auto_increment, c int, key(b)); +create table t1(a int auto_increment, key(a)) type=innodb; +create table t2(b int auto_increment, c int, key(b), foreign key(b) references t1(a)) type=innodb; SET FOREIGN_KEY_CHECKS=0; insert into t1 values (10); insert into t1 values (null),(null),(null); diff --git a/mysql-test/t/rpl_insert_id.test b/mysql-test/t/rpl_insert_id.test index 26d5d3a9ed2..d91bd02883e 100644 --- a/mysql-test/t/rpl_insert_id.test +++ b/mysql-test/t/rpl_insert_id.test @@ -22,8 +22,10 @@ connection master; #are replicated the same way drop table t1; drop table t2; -create table t1(a int auto_increment, key(a)); -create table t2(b int auto_increment, c int, key(b)); +--disable_warnings +create table t1(a int auto_increment, key(a)) type=innodb; +create table t2(b int auto_increment, c int, key(b), foreign key(b) references t1(a)) type=innodb; +--enable_warnings SET FOREIGN_KEY_CHECKS=0; insert into t1 values (10); insert into t1 values (null),(null),(null); From 4eccbd87cdaec8afaa83a26a34b858b32069d3ce Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Mon, 28 Jul 2003 15:33:46 +0200 Subject: [PATCH 202/237] Avoid segfault when LOAD DATA FROM MASTER is run on a master which does no binary logging. --- sql/repl_failsafe.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 1552b3994e9..0a5f90617d1 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -860,7 +860,7 @@ int load_master_data(THD* thd) of LOAD DATA FROM MASTER - no reason to forbid it, really, although it does not make much sense for the user to do it */ - if (row[0] && row[1]) + if (row && row[0] && row[1]) { strmake(active_mi->master_log_name, row[0], sizeof(active_mi->master_log_name)); From c46f888fe39fd93166cdc6ded6cbd04da1b2b836 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Mon, 28 Jul 2003 17:50:06 +0200 Subject: [PATCH 203/237] Followup to Jim's changes in mysqldoc tree. Unfortunately, it's too late for 4.0.14 :( --- Docs/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Docs/Makefile.am b/Docs/Makefile.am index 26249028539..17450c3b072 100644 --- a/Docs/Makefile.am +++ b/Docs/Makefile.am @@ -40,10 +40,10 @@ paper: manual_a4.ps manual_letter.ps $(PDFMANUAL) # The Makefile contains the previous version so we can not use that include.texi: ../configure.in echo "@c This file is autogenerated by the Makefile" > $@ - echo -n "@set mysql_version " >> $@ + echo -n "@set mysqlversion " >> $@ grep "AM_INIT_AUTOMAKE(mysql, " ../configure.in | \ sed -e 's;AM_INIT_AUTOMAKE(mysql, ;;' -e 's;);;' >> $@ - echo -n "@set default_port " >> $@ + echo -n "@set defaultport " >> $@ grep "MYSQL_TCP_PORT_DEFAULT=" ../configure.in | \ sed -e 's;MYSQL_TCP_PORT_DEFAULT=;;' >> $@ From a5eacc69e6a0571ab9c91dd60f43fce195d72a27 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Tue, 29 Jul 2003 00:04:56 +0300 Subject: [PATCH 204/237] mysqld.cc: innodb_fast_shutdown CAN take an argument though it was not specified so in mysqld.cc --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index cbd8ebd350b..41807285acc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3346,7 +3346,7 @@ struct my_option my_long_options[] = 0, 0, 0}, {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN, "Speeds up server shutdown process", (gptr*) &innobase_fast_shutdown, - (gptr*) &innobase_fast_shutdown, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + (gptr*) &innobase_fast_shutdown, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, {"innodb_max_dirty_pages_pct", OPT_INNODB_MAX_DIRTY_PAGES_PCT, "Percentage of dirty pages allowed in bufferpool", (gptr*) &srv_max_buf_pool_modified_pct, (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, From d7ea863d6b9d2648620122accc05cfd2cfc7c105 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Wed, 30 Jul 2003 01:12:33 +0300 Subject: [PATCH 205/237] dict0dict.c: Fix bug introduced in 4.0.13 and reported by Emic: if a CREATE TABLE ended in a comment, a memory overrun could happen --- innobase/dict/dict0dict.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index b1d7b5f762e..924fa3ecf95 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -2405,9 +2405,12 @@ dict_strip_comments( ptr = str; for (;;) { +scan_more: if (*sptr == '\0') { *ptr = '\0'; + ut_a(ptr <= str + strlen(sql_string)); + return(str); } @@ -2421,7 +2424,7 @@ dict_strip_comments( || *sptr == (char)0x0D || *sptr == '\0') { - break; + goto scan_more; } sptr++; @@ -2435,12 +2438,12 @@ dict_strip_comments( sptr += 2; - break; + goto scan_more; } if (*sptr == '\0') { - break; + goto scan_more; } sptr++; From 8f50cd04724b4daf54cd246a0599ef5902406099 Mon Sep 17 00:00:00 2001 From: "dlenev@mysql.com" <> Date: Wed, 30 Jul 2003 03:33:48 +0400 Subject: [PATCH 206/237] Fix security bug. mysqld server without ssl support was completly ignorant about ssl_type attribute --- BitKeeper/etc/logging_ok | 1 + sql/sql_acl.cc | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index e6124b4111e..edb3f4141da 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -15,6 +15,7 @@ bell@laptop.sanja.is.com.ua bell@sanja.is.com.ua bk@admin.bk davida@isil.mysql.com +dlenev@mysql.com gluh@gluh.(none) gluh@gluh.mysql.r18.ru greg@gcw.ath.cx diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 755a72bec32..1f311e651dd 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -530,7 +530,6 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, !check_scramble(password,message,acl_user->salt, (my_bool) old_ver))) { -#ifdef HAVE_OPENSSL Vio *vio=thd->net.vio; /* In this point we know that user is allowed to connect @@ -543,6 +542,7 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, case SSL_TYPE_NONE: /* SSL is not required to connect */ user_access=acl_user->access; break; +#ifdef HAVE_OPENSSL case SSL_TYPE_ANY: /* Any kind of SSL is good enough */ if (vio_type(vio) == VIO_TYPE_SSL) user_access=acl_user->access; @@ -625,10 +625,16 @@ ulong acl_getroot(THD *thd, const char *host, const char *ip, const char *user, } break; } - } #else /* HAVE_OPENSSL */ - user_access=acl_user->access; + default: + /* + If we don't have SSL but SSL is required for this user the + authentication should fail. + */ + break; #endif /* HAVE_OPENSSL */ + } + *mqh=acl_user->user_resource; if (!acl_user->user) *priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */ From 86e6cf399e7594d022b31402f73c691d775b18ec Mon Sep 17 00:00:00 2001 From: "bell@sanja.is.com.ua" <> Date: Wed, 30 Jul 2003 14:59:56 +0300 Subject: [PATCH 207/237] support of more then 255 tables dependence in query cache (fixed BUG#930) --- mysql-test/r/query_cache.result | 535 +++++++++++++++++++++++++++++++- mysql-test/t/query_cache.test | 530 ++++++++++++++++++++++++++++++- sql/sql_cache.h | 2 +- 3 files changed, 1064 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 0ef0cab423b..e1fd5443580 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -2,7 +2,7 @@ flush query cache; flush query cache; reset query cache; flush status; -drop table if exists t1,t2,t3,t11,t21, mysqltest.t1; +drop table if exists t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t00,mysqltest.t1; drop database if exists mysqltest; create table t1 (a int not null); insert into t1 values (1),(2),(3); @@ -640,3 +640,536 @@ Variable_name Value Qcache_queries_in_cache 2 SET OPTION SQL_SELECT_LIMIT=DEFAULT; drop table t1; +flush status; +create table t0(a int); +create table t1(a int); +create table t2(a int); +create table t3(a int); +create table t4(a int); +create table t5(a int); +create table t6(a int); +create table t7(a int); +create table t8(a int); +create table t9(a int); +create table t10(a int); +create table t11(a int); +create table t12(a int); +create table t13(a int); +create table t14(a int); +create table t15(a int); +create table t16(a int); +create table t17(a int); +create table t18(a int); +create table t19(a int); +create table t20(a int); +create table t21(a int); +create table t22(a int); +create table t23(a int); +create table t24(a int); +create table t25(a int); +create table t26(a int); +create table t27(a int); +create table t28(a int); +create table t29(a int); +create table t30(a int); +create table t31(a int); +create table t32(a int); +create table t33(a int); +create table t34(a int); +create table t35(a int); +create table t36(a int); +create table t37(a int); +create table t38(a int); +create table t39(a int); +create table t40(a int); +create table t41(a int); +create table t42(a int); +create table t43(a int); +create table t44(a int); +create table t45(a int); +create table t46(a int); +create table t47(a int); +create table t48(a int); +create table t49(a int); +create table t50(a int); +create table t51(a int); +create table t52(a int); +create table t53(a int); +create table t54(a int); +create table t55(a int); +create table t56(a int); +create table t57(a int); +create table t58(a int); +create table t59(a int); +create table t60(a int); +create table t61(a int); +create table t62(a int); +create table t63(a int); +create table t64(a int); +create table t65(a int); +create table t66(a int); +create table t67(a int); +create table t68(a int); +create table t69(a int); +create table t70(a int); +create table t71(a int); +create table t72(a int); +create table t73(a int); +create table t74(a int); +create table t75(a int); +create table t76(a int); +create table t77(a int); +create table t78(a int); +create table t79(a int); +create table t80(a int); +create table t81(a int); +create table t82(a int); +create table t83(a int); +create table t84(a int); +create table t85(a int); +create table t86(a int); +create table t87(a int); +create table t88(a int); +create table t89(a int); +create table t90(a int); +create table t91(a int); +create table t92(a int); +create table t93(a int); +create table t94(a int); +create table t95(a int); +create table t96(a int); +create table t97(a int); +create table t98(a int); +create table t99(a int); +create table t100(a int); +create table t101(a int); +create table t102(a int); +create table t103(a int); +create table t104(a int); +create table t105(a int); +create table t106(a int); +create table t107(a int); +create table t108(a int); +create table t109(a int); +create table t110(a int); +create table t111(a int); +create table t112(a int); +create table t113(a int); +create table t114(a int); +create table t115(a int); +create table t116(a int); +create table t117(a int); +create table t118(a int); +create table t119(a int); +create table t120(a int); +create table t121(a int); +create table t122(a int); +create table t123(a int); +create table t124(a int); +create table t125(a int); +create table t126(a int); +create table t127(a int); +create table t128(a int); +create table t129(a int); +create table t130(a int); +create table t131(a int); +create table t132(a int); +create table t133(a int); +create table t134(a int); +create table t135(a int); +create table t136(a int); +create table t137(a int); +create table t138(a int); +create table t139(a int); +create table t140(a int); +create table t141(a int); +create table t142(a int); +create table t143(a int); +create table t144(a int); +create table t145(a int); +create table t146(a int); +create table t147(a int); +create table t148(a int); +create table t149(a int); +create table t150(a int); +create table t151(a int); +create table t152(a int); +create table t153(a int); +create table t154(a int); +create table t155(a int); +create table t156(a int); +create table t157(a int); +create table t158(a int); +create table t159(a int); +create table t160(a int); +create table t161(a int); +create table t162(a int); +create table t163(a int); +create table t164(a int); +create table t165(a int); +create table t166(a int); +create table t167(a int); +create table t168(a int); +create table t169(a int); +create table t170(a int); +create table t171(a int); +create table t172(a int); +create table t173(a int); +create table t174(a int); +create table t175(a int); +create table t176(a int); +create table t177(a int); +create table t178(a int); +create table t179(a int); +create table t180(a int); +create table t181(a int); +create table t182(a int); +create table t183(a int); +create table t184(a int); +create table t185(a int); +create table t186(a int); +create table t187(a int); +create table t188(a int); +create table t189(a int); +create table t190(a int); +create table t191(a int); +create table t192(a int); +create table t193(a int); +create table t194(a int); +create table t195(a int); +create table t196(a int); +create table t197(a int); +create table t198(a int); +create table t199(a int); +create table t200(a int); +create table t201(a int); +create table t202(a int); +create table t203(a int); +create table t204(a int); +create table t205(a int); +create table t206(a int); +create table t207(a int); +create table t208(a int); +create table t209(a int); +create table t210(a int); +create table t211(a int); +create table t212(a int); +create table t213(a int); +create table t214(a int); +create table t215(a int); +create table t216(a int); +create table t217(a int); +create table t218(a int); +create table t219(a int); +create table t220(a int); +create table t221(a int); +create table t222(a int); +create table t223(a int); +create table t224(a int); +create table t225(a int); +create table t226(a int); +create table t227(a int); +create table t228(a int); +create table t229(a int); +create table t230(a int); +create table t231(a int); +create table t232(a int); +create table t233(a int); +create table t234(a int); +create table t235(a int); +create table t236(a int); +create table t237(a int); +create table t238(a int); +create table t239(a int); +create table t240(a int); +create table t241(a int); +create table t242(a int); +create table t243(a int); +create table t244(a int); +create table t245(a int); +create table t246(a int); +create table t247(a int); +create table t248(a int); +create table t249(a int); +create table t250(a int); +create table t251(a int); +create table t252(a int); +create table t253(a int); +create table t254(a int); +create table t255(a int); +create table t256(a int); +create table t00 (a int) type=MERGE UNION=(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256) INSERT_METHOD=FIRST; +insert into t0 values (1),(2); +insert into t1 values (1),(2); +insert into t2 values (1),(2); +insert into t3 values (1),(2); +insert into t4 values (1),(2); +insert into t5 values (1),(2); +insert into t6 values (1),(2); +insert into t7 values (1),(2); +insert into t8 values (1),(2); +insert into t9 values (1),(2); +insert into t10 values (1),(2); +insert into t11 values (1),(2); +insert into t12 values (1),(2); +insert into t13 values (1),(2); +insert into t14 values (1),(2); +insert into t15 values (1),(2); +insert into t16 values (1),(2); +insert into t17 values (1),(2); +insert into t18 values (1),(2); +insert into t19 values (1),(2); +insert into t20 values (1),(2); +insert into t21 values (1),(2); +insert into t22 values (1),(2); +insert into t23 values (1),(2); +insert into t24 values (1),(2); +insert into t25 values (1),(2); +insert into t26 values (1),(2); +insert into t27 values (1),(2); +insert into t28 values (1),(2); +insert into t29 values (1),(2); +insert into t30 values (1),(2); +insert into t31 values (1),(2); +insert into t32 values (1),(2); +insert into t33 values (1),(2); +insert into t34 values (1),(2); +insert into t35 values (1),(2); +insert into t36 values (1),(2); +insert into t37 values (1),(2); +insert into t38 values (1),(2); +insert into t39 values (1),(2); +insert into t40 values (1),(2); +insert into t41 values (1),(2); +insert into t42 values (1),(2); +insert into t43 values (1),(2); +insert into t44 values (1),(2); +insert into t45 values (1),(2); +insert into t46 values (1),(2); +insert into t47 values (1),(2); +insert into t48 values (1),(2); +insert into t49 values (1),(2); +insert into t50 values (1),(2); +insert into t51 values (1),(2); +insert into t52 values (1),(2); +insert into t53 values (1),(2); +insert into t54 values (1),(2); +insert into t55 values (1),(2); +insert into t56 values (1),(2); +insert into t57 values (1),(2); +insert into t58 values (1),(2); +insert into t59 values (1),(2); +insert into t60 values (1),(2); +insert into t61 values (1),(2); +insert into t62 values (1),(2); +insert into t63 values (1),(2); +insert into t64 values (1),(2); +insert into t65 values (1),(2); +insert into t66 values (1),(2); +insert into t67 values (1),(2); +insert into t68 values (1),(2); +insert into t69 values (1),(2); +insert into t70 values (1),(2); +insert into t71 values (1),(2); +insert into t72 values (1),(2); +insert into t73 values (1),(2); +insert into t74 values (1),(2); +insert into t75 values (1),(2); +insert into t76 values (1),(2); +insert into t77 values (1),(2); +insert into t78 values (1),(2); +insert into t79 values (1),(2); +insert into t80 values (1),(2); +insert into t81 values (1),(2); +insert into t82 values (1),(2); +insert into t83 values (1),(2); +insert into t84 values (1),(2); +insert into t85 values (1),(2); +insert into t86 values (1),(2); +insert into t87 values (1),(2); +insert into t88 values (1),(2); +insert into t89 values (1),(2); +insert into t90 values (1),(2); +insert into t91 values (1),(2); +insert into t92 values (1),(2); +insert into t93 values (1),(2); +insert into t94 values (1),(2); +insert into t95 values (1),(2); +insert into t96 values (1),(2); +insert into t97 values (1),(2); +insert into t98 values (1),(2); +insert into t99 values (1),(2); +insert into t100 values (1),(2); +insert into t101 values (1),(2); +insert into t102 values (1),(2); +insert into t103 values (1),(2); +insert into t104 values (1),(2); +insert into t105 values (1),(2); +insert into t106 values (1),(2); +insert into t107 values (1),(2); +insert into t108 values (1),(2); +insert into t109 values (1),(2); +insert into t110 values (1),(2); +insert into t111 values (1),(2); +insert into t112 values (1),(2); +insert into t113 values (1),(2); +insert into t114 values (1),(2); +insert into t115 values (1),(2); +insert into t116 values (1),(2); +insert into t117 values (1),(2); +insert into t118 values (1),(2); +insert into t119 values (1),(2); +insert into t120 values (1),(2); +insert into t121 values (1),(2); +insert into t122 values (1),(2); +insert into t123 values (1),(2); +insert into t124 values (1),(2); +insert into t125 values (1),(2); +insert into t126 values (1),(2); +insert into t127 values (1),(2); +insert into t128 values (1),(2); +insert into t129 values (1),(2); +insert into t130 values (1),(2); +insert into t131 values (1),(2); +insert into t132 values (1),(2); +insert into t133 values (1),(2); +insert into t134 values (1),(2); +insert into t135 values (1),(2); +insert into t136 values (1),(2); +insert into t137 values (1),(2); +insert into t138 values (1),(2); +insert into t139 values (1),(2); +insert into t140 values (1),(2); +insert into t141 values (1),(2); +insert into t142 values (1),(2); +insert into t143 values (1),(2); +insert into t144 values (1),(2); +insert into t145 values (1),(2); +insert into t146 values (1),(2); +insert into t147 values (1),(2); +insert into t148 values (1),(2); +insert into t149 values (1),(2); +insert into t150 values (1),(2); +insert into t151 values (1),(2); +insert into t152 values (1),(2); +insert into t153 values (1),(2); +insert into t154 values (1),(2); +insert into t155 values (1),(2); +insert into t156 values (1),(2); +insert into t157 values (1),(2); +insert into t158 values (1),(2); +insert into t159 values (1),(2); +insert into t160 values (1),(2); +insert into t161 values (1),(2); +insert into t162 values (1),(2); +insert into t163 values (1),(2); +insert into t164 values (1),(2); +insert into t165 values (1),(2); +insert into t166 values (1),(2); +insert into t167 values (1),(2); +insert into t168 values (1),(2); +insert into t169 values (1),(2); +insert into t170 values (1),(2); +insert into t171 values (1),(2); +insert into t172 values (1),(2); +insert into t173 values (1),(2); +insert into t174 values (1),(2); +insert into t175 values (1),(2); +insert into t176 values (1),(2); +insert into t177 values (1),(2); +insert into t178 values (1),(2); +insert into t179 values (1),(2); +insert into t180 values (1),(2); +insert into t181 values (1),(2); +insert into t182 values (1),(2); +insert into t183 values (1),(2); +insert into t184 values (1),(2); +insert into t185 values (1),(2); +insert into t186 values (1),(2); +insert into t187 values (1),(2); +insert into t188 values (1),(2); +insert into t189 values (1),(2); +insert into t190 values (1),(2); +insert into t191 values (1),(2); +insert into t192 values (1),(2); +insert into t193 values (1),(2); +insert into t194 values (1),(2); +insert into t195 values (1),(2); +insert into t196 values (1),(2); +insert into t197 values (1),(2); +insert into t198 values (1),(2); +insert into t199 values (1),(2); +insert into t200 values (1),(2); +insert into t201 values (1),(2); +insert into t202 values (1),(2); +insert into t203 values (1),(2); +insert into t204 values (1),(2); +insert into t205 values (1),(2); +insert into t206 values (1),(2); +insert into t207 values (1),(2); +insert into t208 values (1),(2); +insert into t209 values (1),(2); +insert into t210 values (1),(2); +insert into t211 values (1),(2); +insert into t212 values (1),(2); +insert into t213 values (1),(2); +insert into t214 values (1),(2); +insert into t215 values (1),(2); +insert into t216 values (1),(2); +insert into t217 values (1),(2); +insert into t218 values (1),(2); +insert into t219 values (1),(2); +insert into t220 values (1),(2); +insert into t221 values (1),(2); +insert into t222 values (1),(2); +insert into t223 values (1),(2); +insert into t224 values (1),(2); +insert into t225 values (1),(2); +insert into t226 values (1),(2); +insert into t227 values (1),(2); +insert into t228 values (1),(2); +insert into t229 values (1),(2); +insert into t230 values (1),(2); +insert into t231 values (1),(2); +insert into t232 values (1),(2); +insert into t233 values (1),(2); +insert into t234 values (1),(2); +insert into t235 values (1),(2); +insert into t236 values (1),(2); +insert into t237 values (1),(2); +insert into t238 values (1),(2); +insert into t239 values (1),(2); +insert into t240 values (1),(2); +insert into t241 values (1),(2); +insert into t242 values (1),(2); +insert into t243 values (1),(2); +insert into t244 values (1),(2); +insert into t245 values (1),(2); +insert into t246 values (1),(2); +insert into t247 values (1),(2); +insert into t248 values (1),(2); +insert into t249 values (1),(2); +insert into t250 values (1),(2); +insert into t251 values (1),(2); +insert into t252 values (1),(2); +insert into t253 values (1),(2); +insert into t254 values (1),(2); +insert into t255 values (1),(2); +insert into t256 values (1),(2); +select count(*) from t00; +count(*) +514 +select count(*) from t00; +count(*) +514 +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 1 +show status like "Qcache_hits"; +Variable_name Value +Qcache_hits 1 +delete from t256; +show status like "Qcache_queries_in_cache"; +Variable_name Value +Qcache_queries_in_cache 0 +drop table t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t00; diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index fe258b2c7e1..6907a9e8299 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -10,7 +10,7 @@ flush query cache; # This crashed in some versions flush query cache; # This crashed in some versions reset query cache; flush status; -drop table if exists t1,t2,t3,t11,t21, mysqltest.t1; +drop table if exists t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t00,mysqltest.t1; drop database if exists mysqltest; # @@ -450,3 +450,531 @@ select * from t1; show status like "Qcache_queries_in_cache"; SET OPTION SQL_SELECT_LIMIT=DEFAULT; drop table t1; + +# +# more then 255 (257) merged tables test +# +flush status; +create table t0(a int); +create table t1(a int); +create table t2(a int); +create table t3(a int); +create table t4(a int); +create table t5(a int); +create table t6(a int); +create table t7(a int); +create table t8(a int); +create table t9(a int); +create table t10(a int); +create table t11(a int); +create table t12(a int); +create table t13(a int); +create table t14(a int); +create table t15(a int); +create table t16(a int); +create table t17(a int); +create table t18(a int); +create table t19(a int); +create table t20(a int); +create table t21(a int); +create table t22(a int); +create table t23(a int); +create table t24(a int); +create table t25(a int); +create table t26(a int); +create table t27(a int); +create table t28(a int); +create table t29(a int); +create table t30(a int); +create table t31(a int); +create table t32(a int); +create table t33(a int); +create table t34(a int); +create table t35(a int); +create table t36(a int); +create table t37(a int); +create table t38(a int); +create table t39(a int); +create table t40(a int); +create table t41(a int); +create table t42(a int); +create table t43(a int); +create table t44(a int); +create table t45(a int); +create table t46(a int); +create table t47(a int); +create table t48(a int); +create table t49(a int); +create table t50(a int); +create table t51(a int); +create table t52(a int); +create table t53(a int); +create table t54(a int); +create table t55(a int); +create table t56(a int); +create table t57(a int); +create table t58(a int); +create table t59(a int); +create table t60(a int); +create table t61(a int); +create table t62(a int); +create table t63(a int); +create table t64(a int); +create table t65(a int); +create table t66(a int); +create table t67(a int); +create table t68(a int); +create table t69(a int); +create table t70(a int); +create table t71(a int); +create table t72(a int); +create table t73(a int); +create table t74(a int); +create table t75(a int); +create table t76(a int); +create table t77(a int); +create table t78(a int); +create table t79(a int); +create table t80(a int); +create table t81(a int); +create table t82(a int); +create table t83(a int); +create table t84(a int); +create table t85(a int); +create table t86(a int); +create table t87(a int); +create table t88(a int); +create table t89(a int); +create table t90(a int); +create table t91(a int); +create table t92(a int); +create table t93(a int); +create table t94(a int); +create table t95(a int); +create table t96(a int); +create table t97(a int); +create table t98(a int); +create table t99(a int); +create table t100(a int); +create table t101(a int); +create table t102(a int); +create table t103(a int); +create table t104(a int); +create table t105(a int); +create table t106(a int); +create table t107(a int); +create table t108(a int); +create table t109(a int); +create table t110(a int); +create table t111(a int); +create table t112(a int); +create table t113(a int); +create table t114(a int); +create table t115(a int); +create table t116(a int); +create table t117(a int); +create table t118(a int); +create table t119(a int); +create table t120(a int); +create table t121(a int); +create table t122(a int); +create table t123(a int); +create table t124(a int); +create table t125(a int); +create table t126(a int); +create table t127(a int); +create table t128(a int); +create table t129(a int); +create table t130(a int); +create table t131(a int); +create table t132(a int); +create table t133(a int); +create table t134(a int); +create table t135(a int); +create table t136(a int); +create table t137(a int); +create table t138(a int); +create table t139(a int); +create table t140(a int); +create table t141(a int); +create table t142(a int); +create table t143(a int); +create table t144(a int); +create table t145(a int); +create table t146(a int); +create table t147(a int); +create table t148(a int); +create table t149(a int); +create table t150(a int); +create table t151(a int); +create table t152(a int); +create table t153(a int); +create table t154(a int); +create table t155(a int); +create table t156(a int); +create table t157(a int); +create table t158(a int); +create table t159(a int); +create table t160(a int); +create table t161(a int); +create table t162(a int); +create table t163(a int); +create table t164(a int); +create table t165(a int); +create table t166(a int); +create table t167(a int); +create table t168(a int); +create table t169(a int); +create table t170(a int); +create table t171(a int); +create table t172(a int); +create table t173(a int); +create table t174(a int); +create table t175(a int); +create table t176(a int); +create table t177(a int); +create table t178(a int); +create table t179(a int); +create table t180(a int); +create table t181(a int); +create table t182(a int); +create table t183(a int); +create table t184(a int); +create table t185(a int); +create table t186(a int); +create table t187(a int); +create table t188(a int); +create table t189(a int); +create table t190(a int); +create table t191(a int); +create table t192(a int); +create table t193(a int); +create table t194(a int); +create table t195(a int); +create table t196(a int); +create table t197(a int); +create table t198(a int); +create table t199(a int); +create table t200(a int); +create table t201(a int); +create table t202(a int); +create table t203(a int); +create table t204(a int); +create table t205(a int); +create table t206(a int); +create table t207(a int); +create table t208(a int); +create table t209(a int); +create table t210(a int); +create table t211(a int); +create table t212(a int); +create table t213(a int); +create table t214(a int); +create table t215(a int); +create table t216(a int); +create table t217(a int); +create table t218(a int); +create table t219(a int); +create table t220(a int); +create table t221(a int); +create table t222(a int); +create table t223(a int); +create table t224(a int); +create table t225(a int); +create table t226(a int); +create table t227(a int); +create table t228(a int); +create table t229(a int); +create table t230(a int); +create table t231(a int); +create table t232(a int); +create table t233(a int); +create table t234(a int); +create table t235(a int); +create table t236(a int); +create table t237(a int); +create table t238(a int); +create table t239(a int); +create table t240(a int); +create table t241(a int); +create table t242(a int); +create table t243(a int); +create table t244(a int); +create table t245(a int); +create table t246(a int); +create table t247(a int); +create table t248(a int); +create table t249(a int); +create table t250(a int); +create table t251(a int); +create table t252(a int); +create table t253(a int); +create table t254(a int); +create table t255(a int); +create table t256(a int); +create table t00 (a int) type=MERGE UNION=(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256) INSERT_METHOD=FIRST; +insert into t0 values (1),(2); +insert into t1 values (1),(2); +insert into t2 values (1),(2); +insert into t3 values (1),(2); +insert into t4 values (1),(2); +insert into t5 values (1),(2); +insert into t6 values (1),(2); +insert into t7 values (1),(2); +insert into t8 values (1),(2); +insert into t9 values (1),(2); +insert into t10 values (1),(2); +insert into t11 values (1),(2); +insert into t12 values (1),(2); +insert into t13 values (1),(2); +insert into t14 values (1),(2); +insert into t15 values (1),(2); +insert into t16 values (1),(2); +insert into t17 values (1),(2); +insert into t18 values (1),(2); +insert into t19 values (1),(2); +insert into t20 values (1),(2); +insert into t21 values (1),(2); +insert into t22 values (1),(2); +insert into t23 values (1),(2); +insert into t24 values (1),(2); +insert into t25 values (1),(2); +insert into t26 values (1),(2); +insert into t27 values (1),(2); +insert into t28 values (1),(2); +insert into t29 values (1),(2); +insert into t30 values (1),(2); +insert into t31 values (1),(2); +insert into t32 values (1),(2); +insert into t33 values (1),(2); +insert into t34 values (1),(2); +insert into t35 values (1),(2); +insert into t36 values (1),(2); +insert into t37 values (1),(2); +insert into t38 values (1),(2); +insert into t39 values (1),(2); +insert into t40 values (1),(2); +insert into t41 values (1),(2); +insert into t42 values (1),(2); +insert into t43 values (1),(2); +insert into t44 values (1),(2); +insert into t45 values (1),(2); +insert into t46 values (1),(2); +insert into t47 values (1),(2); +insert into t48 values (1),(2); +insert into t49 values (1),(2); +insert into t50 values (1),(2); +insert into t51 values (1),(2); +insert into t52 values (1),(2); +insert into t53 values (1),(2); +insert into t54 values (1),(2); +insert into t55 values (1),(2); +insert into t56 values (1),(2); +insert into t57 values (1),(2); +insert into t58 values (1),(2); +insert into t59 values (1),(2); +insert into t60 values (1),(2); +insert into t61 values (1),(2); +insert into t62 values (1),(2); +insert into t63 values (1),(2); +insert into t64 values (1),(2); +insert into t65 values (1),(2); +insert into t66 values (1),(2); +insert into t67 values (1),(2); +insert into t68 values (1),(2); +insert into t69 values (1),(2); +insert into t70 values (1),(2); +insert into t71 values (1),(2); +insert into t72 values (1),(2); +insert into t73 values (1),(2); +insert into t74 values (1),(2); +insert into t75 values (1),(2); +insert into t76 values (1),(2); +insert into t77 values (1),(2); +insert into t78 values (1),(2); +insert into t79 values (1),(2); +insert into t80 values (1),(2); +insert into t81 values (1),(2); +insert into t82 values (1),(2); +insert into t83 values (1),(2); +insert into t84 values (1),(2); +insert into t85 values (1),(2); +insert into t86 values (1),(2); +insert into t87 values (1),(2); +insert into t88 values (1),(2); +insert into t89 values (1),(2); +insert into t90 values (1),(2); +insert into t91 values (1),(2); +insert into t92 values (1),(2); +insert into t93 values (1),(2); +insert into t94 values (1),(2); +insert into t95 values (1),(2); +insert into t96 values (1),(2); +insert into t97 values (1),(2); +insert into t98 values (1),(2); +insert into t99 values (1),(2); +insert into t100 values (1),(2); +insert into t101 values (1),(2); +insert into t102 values (1),(2); +insert into t103 values (1),(2); +insert into t104 values (1),(2); +insert into t105 values (1),(2); +insert into t106 values (1),(2); +insert into t107 values (1),(2); +insert into t108 values (1),(2); +insert into t109 values (1),(2); +insert into t110 values (1),(2); +insert into t111 values (1),(2); +insert into t112 values (1),(2); +insert into t113 values (1),(2); +insert into t114 values (1),(2); +insert into t115 values (1),(2); +insert into t116 values (1),(2); +insert into t117 values (1),(2); +insert into t118 values (1),(2); +insert into t119 values (1),(2); +insert into t120 values (1),(2); +insert into t121 values (1),(2); +insert into t122 values (1),(2); +insert into t123 values (1),(2); +insert into t124 values (1),(2); +insert into t125 values (1),(2); +insert into t126 values (1),(2); +insert into t127 values (1),(2); +insert into t128 values (1),(2); +insert into t129 values (1),(2); +insert into t130 values (1),(2); +insert into t131 values (1),(2); +insert into t132 values (1),(2); +insert into t133 values (1),(2); +insert into t134 values (1),(2); +insert into t135 values (1),(2); +insert into t136 values (1),(2); +insert into t137 values (1),(2); +insert into t138 values (1),(2); +insert into t139 values (1),(2); +insert into t140 values (1),(2); +insert into t141 values (1),(2); +insert into t142 values (1),(2); +insert into t143 values (1),(2); +insert into t144 values (1),(2); +insert into t145 values (1),(2); +insert into t146 values (1),(2); +insert into t147 values (1),(2); +insert into t148 values (1),(2); +insert into t149 values (1),(2); +insert into t150 values (1),(2); +insert into t151 values (1),(2); +insert into t152 values (1),(2); +insert into t153 values (1),(2); +insert into t154 values (1),(2); +insert into t155 values (1),(2); +insert into t156 values (1),(2); +insert into t157 values (1),(2); +insert into t158 values (1),(2); +insert into t159 values (1),(2); +insert into t160 values (1),(2); +insert into t161 values (1),(2); +insert into t162 values (1),(2); +insert into t163 values (1),(2); +insert into t164 values (1),(2); +insert into t165 values (1),(2); +insert into t166 values (1),(2); +insert into t167 values (1),(2); +insert into t168 values (1),(2); +insert into t169 values (1),(2); +insert into t170 values (1),(2); +insert into t171 values (1),(2); +insert into t172 values (1),(2); +insert into t173 values (1),(2); +insert into t174 values (1),(2); +insert into t175 values (1),(2); +insert into t176 values (1),(2); +insert into t177 values (1),(2); +insert into t178 values (1),(2); +insert into t179 values (1),(2); +insert into t180 values (1),(2); +insert into t181 values (1),(2); +insert into t182 values (1),(2); +insert into t183 values (1),(2); +insert into t184 values (1),(2); +insert into t185 values (1),(2); +insert into t186 values (1),(2); +insert into t187 values (1),(2); +insert into t188 values (1),(2); +insert into t189 values (1),(2); +insert into t190 values (1),(2); +insert into t191 values (1),(2); +insert into t192 values (1),(2); +insert into t193 values (1),(2); +insert into t194 values (1),(2); +insert into t195 values (1),(2); +insert into t196 values (1),(2); +insert into t197 values (1),(2); +insert into t198 values (1),(2); +insert into t199 values (1),(2); +insert into t200 values (1),(2); +insert into t201 values (1),(2); +insert into t202 values (1),(2); +insert into t203 values (1),(2); +insert into t204 values (1),(2); +insert into t205 values (1),(2); +insert into t206 values (1),(2); +insert into t207 values (1),(2); +insert into t208 values (1),(2); +insert into t209 values (1),(2); +insert into t210 values (1),(2); +insert into t211 values (1),(2); +insert into t212 values (1),(2); +insert into t213 values (1),(2); +insert into t214 values (1),(2); +insert into t215 values (1),(2); +insert into t216 values (1),(2); +insert into t217 values (1),(2); +insert into t218 values (1),(2); +insert into t219 values (1),(2); +insert into t220 values (1),(2); +insert into t221 values (1),(2); +insert into t222 values (1),(2); +insert into t223 values (1),(2); +insert into t224 values (1),(2); +insert into t225 values (1),(2); +insert into t226 values (1),(2); +insert into t227 values (1),(2); +insert into t228 values (1),(2); +insert into t229 values (1),(2); +insert into t230 values (1),(2); +insert into t231 values (1),(2); +insert into t232 values (1),(2); +insert into t233 values (1),(2); +insert into t234 values (1),(2); +insert into t235 values (1),(2); +insert into t236 values (1),(2); +insert into t237 values (1),(2); +insert into t238 values (1),(2); +insert into t239 values (1),(2); +insert into t240 values (1),(2); +insert into t241 values (1),(2); +insert into t242 values (1),(2); +insert into t243 values (1),(2); +insert into t244 values (1),(2); +insert into t245 values (1),(2); +insert into t246 values (1),(2); +insert into t247 values (1),(2); +insert into t248 values (1),(2); +insert into t249 values (1),(2); +insert into t250 values (1),(2); +insert into t251 values (1),(2); +insert into t252 values (1),(2); +insert into t253 values (1),(2); +insert into t254 values (1),(2); +insert into t255 values (1),(2); +insert into t256 values (1),(2); +enable_result_log; +select count(*) from t00; +select count(*) from t00; +show status like "Qcache_queries_in_cache"; +show status like "Qcache_hits"; +delete from t256; +show status like "Qcache_queries_in_cache"; +drop table t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40,t41,t42,t43,t44,t45,t46,t47,t48,t49,t50,t51,t52,t53,t54,t55,t56,t57,t58,t59,t60,t61,t62,t63,t64,t65,t66,t67,t68,t69,t70,t71,t72,t73,t74,t75,t76,t77,t78,t79,t80,t81,t82,t83,t84,t85,t86,t87,t88,t89,t90,t91,t92,t93,t94,t95,t96,t97,t98,t99,t100,t101,t102,t103,t104,t105,t106,t107,t108,t109,t110,t111,t112,t113,t114,t115,t116,t117,t118,t119,t120,t121,t122,t123,t124,t125,t126,t127,t128,t129,t130,t131,t132,t133,t134,t135,t136,t137,t138,t139,t140,t141,t142,t143,t144,t145,t146,t147,t148,t149,t150,t151,t152,t153,t154,t155,t156,t157,t158,t159,t160,t161,t162,t163,t164,t165,t166,t167,t168,t169,t170,t171,t172,t173,t174,t175,t176,t177,t178,t179,t180,t181,t182,t183,t184,t185,t186,t187,t188,t189,t190,t191,t192,t193,t194,t195,t196,t197,t198,t199,t200,t201,t202,t203,t204,t205,t206,t207,t208,t209,t210,t211,t212,t213,t214,t215,t216,t217,t218,t219,t220,t221,t222,t223,t224,t225,t226,t227,t228,t229,t230,t231,t232,t233,t234,t235,t236,t237,t238,t239,t240,t241,t242,t243,t244,t245,t246,t247,t248,t249,t250,t251,t252,t253,t254,t255,t256,t00; diff --git a/sql/sql_cache.h b/sql/sql_cache.h index b15df28f54b..74b1a6cee96 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -61,7 +61,7 @@ #define QUERY_CACHE_PACK_ITERATION 2 #define QUERY_CACHE_PACK_LIMIT (512*1024L) -#define TABLE_COUNTER_TYPE uint8 +#define TABLE_COUNTER_TYPE uint struct Query_cache_block; struct Query_cache_block_table; From c8c7aab6a016678429a276f6cd9e9e498294ba82 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Wed, 30 Jul 2003 16:15:10 +0200 Subject: [PATCH 208/237] Bug#937 myisamchk.c: help text clarified mi_check.c: allow one to "analyze" empty table :) --- myisam/mi_check.c | 11 ++++++----- myisam/myisamchk.c | 10 +++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 6caacd95386..4b28a88fc6e 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -3562,11 +3562,12 @@ int update_state_info(MI_CHECK *param, MI_INFO *info,uint update) uint i, key_parts= mi_uint2korr(share->state.header.key_parts); share->state.rec_per_key_rows=info->state->records; share->state.changed&= ~STATE_NOT_ANALYZED; - for (i=0; istate.rec_per_key_part[i]=param->rec_per_key_part[i])) - share->state.changed|= STATE_NOT_ANALYZED; - } + if (info->state->records) + for (i=0; istate.rec_per_key_part[i]=param->rec_per_key_part[i])) + share->state.changed|= STATE_NOT_ANALYZED; + } } if (update & (UPDATE_STAT | UPDATE_SORT | UPDATE_TIME | UPDATE_AUTO_INC)) { diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 882f868e326..1a27e9debe8 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -357,11 +357,15 @@ static void usage(void) -e, --extend-check Check the table VERY throughly. Only use this in\n\ extreme cases as myisamchk should normally be able to\n\ find out if the table is ok even without this switch\n\ - -F, --fast Check only tables that haven't been closed properly\n\ - -C, --check-only-changed\n\ - Check only tables that have changed since last check\n\ + -F, --fast Check only tables that haven't been closed properly.\n\ + It also applies to other requested actions (e.g. --analyze\n\ + will be ignored if the table is already analyzed).\n\ -f, --force Restart with '-r' if there are any errors in the table.\n\ States will be updated as with '--update-state'\n\ + -C, --check-only-changed\n\ + Check only tables that have changed since last check.\n\ + It also applies to other requested actions (e.g. --analyze\n\ + will be ignored if the table is already analyzed).\n\ -i, --information Print statistics information about table that is checked\n\ -m, --medium-check Faster than extend-check, but only finds 99.99% of\n\ all errors. Should be good enough for most cases\n\ From fb5a1da62177b5cfe27cdd4c8a9f5e8f6f91db5a Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Thu, 31 Jul 2003 13:45:35 +0200 Subject: [PATCH 209/237] bug #942. docid == ftb->lastpos in join on looping over nested table --- myisam/ft_boolean_search.c | 4 ++-- mysql-test/r/fulltext.result | 11 +++++++++++ mysql-test/t/fulltext.test | 16 +++++++++++++++- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/myisam/ft_boolean_search.c b/myisam/ft_boolean_search.c index ed6bf1808a9..6a7b7531d4d 100644 --- a/myisam/ft_boolean_search.c +++ b/myisam/ft_boolean_search.c @@ -299,7 +299,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, default_charset_info : info->s->keyinfo[keynr].seg->charset); ftb->with_scan=0; - ftb->lastpos=0; + ftb->lastpos=HA_POS_ERROR; bzero(& ftb->no_dupes, sizeof(TREE)); init_alloc_root(&ftb->mem_root, 1024, 1024); @@ -543,7 +543,7 @@ float ft_boolean_find_relevance(FT_INFO *ftb, byte *record, uint length) if (!ftb->queue.elements) return 0; - if (ftb->state != INDEX_SEARCH && docid < ftb->lastpos) + if (ftb->state != INDEX_SEARCH && docid <= ftb->lastpos) { FTB_EXPR *x; uint i; diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 646c1a7bee2..737390865f1 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -256,3 +256,14 @@ select ref_mag from t1 where match ref_mag against ('+test' in boolean mode); ref_mag test drop table t1; +create table t1 (t1_id int(11) primary key, name varchar(32)); +insert into t1 values (1, 'data1'); +insert into t1 values (2, 'data2'); +create table t2 (t2_id int(11) primary key, t1_id int(11), name varchar(32)); +insert into t2 values (1, 1, 'xxfoo'); +insert into t2 values (2, 1, 'xxbar'); +insert into t2 values (3, 1, 'xxbuz'); +select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode); +t1_id name t2_id t1_id name +1 data1 1 1 xxfoo +drop table t1,t2; diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index 942552f5e98..387a36f1f52 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -189,7 +189,7 @@ select * from t1 where match (a) against ('aaaa'); drop table t1; # -# bug 283 by jocelyn fournier +# bug #283 by jocelyn fournier # FULLTEXT index on a TEXT filed converted to a CHAR field doesn't work anymore # @@ -201,3 +201,17 @@ alter table t1 change ref_mag ref_mag char (255) not null; select ref_mag from t1 where match ref_mag against ('+test' in boolean mode); drop table t1; +# +# bug #942: JOIN +# + +create table t1 (t1_id int(11) primary key, name varchar(32)); +insert into t1 values (1, 'data1'); +insert into t1 values (2, 'data2'); +create table t2 (t2_id int(11) primary key, t1_id int(11), name varchar(32)); +insert into t2 values (1, 1, 'xxfoo'); +insert into t2 values (2, 1, 'xxbar'); +insert into t2 values (3, 1, 'xxbuz'); +select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode); +drop table t1,t2; + From 216ca1e15d4abff653ff22c549a33c2e4c8905f8 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Fri, 1 Aug 2003 10:09:23 +0200 Subject: [PATCH 210/237] - fixed BUG#968 ("test: argument expected" error) - thanks to Alex Kiernan for the patch --- scripts/mysql_fix_privilege_tables.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index 526b7ac91b3..7ba42e560bb 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -4,7 +4,7 @@ root_password="$1" host="localhost" user="root" -if test -z $1 ; then +if test -z "$1" ; then cmd="@bindir@/mysql -f --user=$user --host=$host mysql" else root_password="$1" From 3c007c3de99def8c2294b67669132fcacd82d657 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Fri, 1 Aug 2003 10:21:41 +0200 Subject: [PATCH 211/237] - portability fixes: put string tests in double quotes (BUG#974). Thanks to Alex Kiernan for the hint. --- acinclude.m4 | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index b558e952543..3b9b7ce13b6 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -50,7 +50,7 @@ mysql_cv_btype_last_arg_accept=none ], [int a = accept(1, (struct sockaddr *) 0, (socklen_t *) 0); return (a != 0);], mysql_cv_btype_last_arg_accept=socklen_t)] -if test $mysql_cv_btype_last_arg_accept = none; then +if test "$mysql_cv_btype_last_arg_accept" = "none"; then [AC_TRY_COMPILE([#if defined(inline) #undef inline #endif @@ -61,7 +61,7 @@ if test $mysql_cv_btype_last_arg_accept = none; then [int a = accept(1, (struct sockaddr *) 0, (size_t *) 0); return (a != 0);], mysql_cv_btype_last_arg_accept=size_t)] fi -if test $mysql_cv_btype_last_arg_accept = none; then +if test "$mysql_cv_btype_last_arg_accept" = "none"; then mysql_cv_btype_last_arg_accept=int fi) AC_LANG_RESTORE @@ -353,11 +353,11 @@ AC_CACHE_VAL(mysql_cv_termcap_lib, [AC_CHECK_LIB(termcap, tgetent, mysql_cv_termcap_lib=libtermcap, mysql_cv_termcap_lib=NOT_FOUND)])])]) AC_MSG_CHECKING(for termcap functions library) -if test $mysql_cv_termcap_lib = NOT_FOUND; then +if test "$mysql_cv_termcap_lib" = "NOT_FOUND"; then AC_MSG_ERROR([No curses/termcap library found]) -elif test $mysql_cv_termcap_lib = libtermcap; then +elif test "$mysql_cv_termcap_lib" = "libtermcap"; then TERMCAP_LIB=-ltermcap -elif test $mysql_cv_termcap_lib = libncurses; then +elif test "$mysql_cv_termcap_lib" = "libncurses"; then TERMCAP_LIB=-lncurses else TERMCAP_LIB=-lcurses @@ -413,7 +413,7 @@ AC_CACHE_VAL(mysql_cv_can_redecl_getpw, extern struct passwd *getpwent();], [struct passwd *z; z = getpwent();], mysql_cv_can_redecl_getpw=yes,mysql_cv_can_redecl_getpw=no)]) AC_MSG_RESULT($mysql_cv_can_redecl_getpw) -if test $mysql_cv_can_redecl_getpw = no; then +if test "$mysql_cv_can_redecl_getpw" = "no"; then AC_DEFINE(HAVE_GETPW_DECLS) fi ]) @@ -425,7 +425,7 @@ AC_CACHE_VAL(mysql_cv_tiocgwinsz_in_ioctl, #include ], [int x = TIOCGWINSZ;], mysql_cv_tiocgwinsz_in_ioctl=yes,mysql_cv_tiocgwinsz_in_ioctl=no)]) AC_MSG_RESULT($mysql_cv_tiocgwinsz_in_ioctl) -if test $mysql_cv_tiocgwinsz_in_ioctl = yes; then +if test "$mysql_cv_tiocgwinsz_in_ioctl" = "yes"; then AC_DEFINE(GWINSZ_IN_SYS_IOCTL) fi ]) @@ -437,7 +437,7 @@ AC_CACHE_VAL(mysql_cv_fionread_in_ioctl, #include ], [int x = FIONREAD;], mysql_cv_fionread_in_ioctl=yes,mysql_cv_fionread_in_ioctl=no)]) AC_MSG_RESULT($mysql_cv_fionread_in_ioctl) -if test $mysql_cv_fionread_in_ioctl = yes; then +if test "$mysql_cv_fionread_in_ioctl" = "yes"; then AC_DEFINE(FIONREAD_IN_SYS_IOCTL) fi ]) @@ -449,7 +449,7 @@ AC_CACHE_VAL(mysql_cv_tiocstat_in_ioctl, #include ], [int x = TIOCSTAT;], mysql_cv_tiocstat_in_ioctl=yes,mysql_cv_tiocstat_in_ioctl=no)]) AC_MSG_RESULT($mysql_cv_tiocstat_in_ioctl) -if test $mysql_cv_tiocstat_in_ioctl = yes; then +if test "$mysql_cv_tiocstat_in_ioctl" = "yes"; then AC_DEFINE(TIOCSTAT_IN_SYS_IOCTL) fi ]) @@ -482,7 +482,7 @@ AC_CACHE_VAL(mysql_cv_dirent_has_dino, struct dirent d; int z; z = d.d_ino; ], mysql_cv_dirent_has_dino=yes, mysql_cv_dirent_has_dino=no)]) AC_MSG_RESULT($mysql_cv_dirent_has_dino) -if test $mysql_cv_dirent_has_dino = yes; then +if test "$mysql_cv_dirent_has_dino" = "yes"; then AC_DEFINE(STRUCT_DIRENT_HAS_D_INO) fi ]) @@ -501,7 +501,7 @@ extern "C" void (*signal ()) ();], [int i;], mysql_cv_void_sighandler=yes, mysql_cv_void_sighandler=no)])dnl AC_MSG_RESULT($mysql_cv_void_sighandler) -if test $mysql_cv_void_sighandler = yes; then +if test "$mysql_cv_void_sighandler" = "yes"; then AC_DEFINE(VOID_SIGHANDLER) fi ]) @@ -560,7 +560,7 @@ then AC_CACHE_CHECK([for working alloca.h], ac_cv_header_alloca_h, [AC_TRY_LINK([#include ], [char *p = alloca(2 * sizeof(int));], ac_cv_header_alloca_h=yes, ac_cv_header_alloca_h=no)]) - if test $ac_cv_header_alloca_h = yes + if test "$ac_cv_header_alloca_h" = "yes" then AC_DEFINE(HAVE_ALLOCA) fi @@ -584,11 +584,11 @@ then #endif ], [char *p = (char *) alloca(1);], ac_cv_func_alloca_works=yes, ac_cv_func_alloca_works=no)]) - if test $ac_cv_func_alloca_works = yes; then + if test "$ac_cv_func_alloca_works" = "yes"; then AC_DEFINE(HAVE_ALLOCA) fi - if test $ac_cv_func_alloca_works = no; then + if test "$ac_cv_func_alloca_works" = "no"; then # The SVR3 libPW and SVR4 libucb both contain incompatible functions # that cause trouble. Some versions do not even contain alloca or # contain a buggy version. If you still want to use their alloca, @@ -604,7 +604,7 @@ then wenotbecray #endif ], ac_cv_os_cray=yes, ac_cv_os_cray=no)]) - if test $ac_cv_os_cray = yes; then + if test "$ac_cv_os_cray" = "yes"; then for ac_func in _getb67 GETB67 getb67; do AC_CHECK_FUNC($ac_func, [AC_DEFINE_UNQUOTED(CRAY_STACKSEG_END, $ac_func) break]) @@ -812,7 +812,7 @@ AC_MSG_CHECKING(for OpenSSL) case "$CLIENT_EXTRA_LDFLAGS $MYSQLD_EXTRA_LDFLAGS" in *-all-static*) using_static="yes" ;; esac - if test $using_static = "yes" + if test "$using_static" = "yes" then echo "You can't use the --all-static link option when using openssl." exit 1 From 14f2fc28b6a1c8c8c29d1aef4b9021a571fc2c51 Mon Sep 17 00:00:00 2001 From: "heikki@hundin.mysql.fi" <> Date: Fri, 1 Aug 2003 12:13:52 +0300 Subject: [PATCH 212/237] log0log.c: Fix assertion failure reported by Alex Kiernan when we compile with the SUN Forte Developer 7 C 5.4 compiler --- innobase/log/log0log.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/innobase/log/log0log.c b/innobase/log/log0log.c index 99827da5bf5..1c7a79525e3 100644 --- a/innobase/log/log0log.c +++ b/innobase/log/log0log.c @@ -500,7 +500,7 @@ log_group_calc_lsn_offset( offset = (gr_lsn_size_offset + difference) % group_size; - ut_a(offset <= 0xFFFFFFFF); + ut_a(offset < (((ib_longlong) 1) << 32)); /* offset must be < 4 GB */ /* printf("Offset is %lu gr_lsn_offset is %lu difference is %lu\n", (ulint)offset,(ulint)gr_lsn_size_offset, (ulint)difference); From f131bd53d410286725d06e98827d7bb9172ecdd0 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Fri, 1 Aug 2003 14:58:03 +0200 Subject: [PATCH 213/237] replace mi_rrnd() in myrg_rkey family to more intelligent (HA_KEYREAD-aware) read function --- myisammrg/myrg_def.h | 2 ++ myisammrg/myrg_queue.c | 12 ++++++++++-- myisammrg/myrg_rfirst.c | 2 +- myisammrg/myrg_rkey.c | 4 ++-- myisammrg/myrg_rlast.c | 2 +- myisammrg/myrg_rnext.c | 2 +- myisammrg/myrg_rprev.c | 2 +- 7 files changed, 18 insertions(+), 8 deletions(-) diff --git a/myisammrg/myrg_def.h b/myisammrg/myrg_def.h index d56cf4aa8d8..00e7950bccf 100644 --- a/myisammrg/myrg_def.h +++ b/myisammrg/myrg_def.h @@ -29,3 +29,5 @@ extern pthread_mutex_t THR_LOCK_open; #endif int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag); +int _myrg_mi_read_record(MI_INFO *info, byte *buf); + diff --git a/myisammrg/myrg_queue.c b/myisammrg/myrg_queue.c index b4f729fc2cf..5ec382feb91 100644 --- a/myisammrg/myrg_queue.c +++ b/myisammrg/myrg_queue.c @@ -14,8 +14,6 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Read record based on a key */ - #include "myrg_def.h" static int queue_key_cmp(void *keyseg, byte *a, byte *b) @@ -55,3 +53,13 @@ int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag) } return error; } + +int _myrg_mi_read_record(MI_INFO *info, byte *buf) +{ + if (!(*info->read_record)(info,info->lastpos,buf)) + { + info->update|= HA_STATE_AKTIV; /* Record is read */ + return 0; + } + return my_errno; +} diff --git a/myisammrg/myrg_rfirst.c b/myisammrg/myrg_rfirst.c index 2ee9c015a84..9ba07686c47 100644 --- a/myisammrg/myrg_rfirst.c +++ b/myisammrg/myrg_rfirst.c @@ -45,5 +45,5 @@ int myrg_rfirst(MYRG_INFO *info, byte *buf, int inx) return HA_ERR_END_OF_FILE; mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table; - return mi_rrnd(mi,buf,mi->lastpos); + return _myrg_mi_read_record(mi,buf); } diff --git a/myisammrg/myrg_rkey.c b/myisammrg/myrg_rkey.c index ba042352a51..fbfa7f24921 100644 --- a/myisammrg/myrg_rkey.c +++ b/myisammrg/myrg_rkey.c @@ -36,7 +36,7 @@ SerG */ -int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key, +int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key, uint key_len, enum ha_rkey_function search_flag) { byte *key_buff; @@ -83,5 +83,5 @@ int myrg_rkey(MYRG_INFO *info,byte *record,int inx, const byte *key, return HA_ERR_KEY_NOT_FOUND; mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table; - return mi_rrnd(mi,record,mi->lastpos); + return _myrg_mi_read_record(mi,buf); } diff --git a/myisammrg/myrg_rlast.c b/myisammrg/myrg_rlast.c index e03a07c295a..96bb798bd4f 100644 --- a/myisammrg/myrg_rlast.c +++ b/myisammrg/myrg_rlast.c @@ -45,6 +45,6 @@ int myrg_rlast(MYRG_INFO *info, byte *buf, int inx) return HA_ERR_END_OF_FILE; mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table; - return mi_rrnd(mi,buf,mi->lastpos); + return _myrg_mi_read_record(mi,buf); } diff --git a/myisammrg/myrg_rnext.c b/myisammrg/myrg_rnext.c index 6d657b5926c..0929c63fc1d 100644 --- a/myisammrg/myrg_rnext.c +++ b/myisammrg/myrg_rnext.c @@ -49,5 +49,5 @@ int myrg_rnext(MYRG_INFO *info, byte *buf, int inx) /* now, mymerge's read_next is as simple as one queue_top */ mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table; - return mi_rrnd(mi,buf,mi->lastpos); + return _myrg_mi_read_record(mi,buf); } diff --git a/myisammrg/myrg_rprev.c b/myisammrg/myrg_rprev.c index c21ca06dacd..797993e903d 100644 --- a/myisammrg/myrg_rprev.c +++ b/myisammrg/myrg_rprev.c @@ -49,5 +49,5 @@ int myrg_rprev(MYRG_INFO *info, byte *buf, int inx) /* now, mymerge's read_prev is as simple as one queue_top */ mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table; - return mi_rrnd(mi,buf,mi->lastpos); + return _myrg_mi_read_record(mi,buf); } From 119d3f039df335923787d519083b06e2268c8037 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Fri, 1 Aug 2003 22:29:38 +0200 Subject: [PATCH 214/237] Backporting the changeset below from 4.0, because a customer hits the bug with 3.23. ChangeSet@1.1416.113.1, 2003-03-22 15:22:59+01:00, guilhem@mysql.com Fix for #178 Replicating INSERT VALUES(USER()) crashes (SEGV) the slave Now it does not SEGV, but USER() is still badly replicated (it is replicated to ""), which is a lower priority bug. --- sql/item_strfunc.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 323810398ec..9e37a5a18e5 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1094,7 +1094,8 @@ String *Item_func_database::val_str(String *str) String *Item_func_user::val_str(String *str) { THD *thd=current_thd; - if (str->copy((const char*) thd->user,(uint) strlen(thd->user)) || + if (!(thd->user) || // for system threads (e.g. replication thread) + str->copy((const char*) thd->user,(uint) strlen(thd->user)) || str->append('@') || str->append(thd->host ? thd->host : thd->ip ? thd->ip : "")) return &empty_string; From fa1d0098ec15ced624ab0d05f189a0e9a3849c1e Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 2 Aug 2003 16:10:26 +0200 Subject: [PATCH 215/237] Mark tables 'updating' in sql_acl.cc (mysql_grant(), mysql_table_grant()) so that tables_ok() does not ignore them. This fixes random bug #980. --- sql/sql_acl.cc | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 755a72bec32..d73e8b236e5 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2107,8 +2107,17 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, GRANT and REVOKE are applied the slave in/exclusion rules as they are some kind of updates to the mysql.% tables. */ - if (thd->slave_thread && table_rules_on && !tables_ok(0, tables)) - DBUG_RETURN(0); + if (thd->slave_thread && table_rules_on) + { + /* + The tables must be marked "updating" so that tables_ok() takes them into + account in tests. + */ + tables[0].updating=tables[1].updating=tables[2].updating=1; + if (!tables_ok(0, tables)) + DBUG_RETURN(0); + tables[0].updating=tables[1].updating=tables[2].updating=0; + } #endif if (open_and_lock_tables(thd,tables)) @@ -2279,8 +2288,17 @@ int mysql_grant (THD *thd, const char *db, List &list, GRANT and REVOKE are applied the slave in/exclusion rules as they are some kind of updates to the mysql.% tables. */ - if (thd->slave_thread && table_rules_on && !tables_ok(0, tables)) - DBUG_RETURN(0); + if (thd->slave_thread && table_rules_on) + { + /* + The tables must be marked "updating" so that tables_ok() takes them into + account in tests. + */ + tables[0].updating=tables[1].updating=1; + if (!tables_ok(0, tables)) + DBUG_RETURN(0); + tables[0].updating=tables[1].updating=0; + } #endif if (open_and_lock_tables(thd,tables)) From 41865cf3a670ffee10d0cf263c33e12bd7b8c2da Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Sat, 2 Aug 2003 23:46:26 +0200 Subject: [PATCH 216/237] Fix so that SET PASSWORD is not replicated by the slave if running with replicate-*-table rules which exclude 'mysql' tables (e.g. replicate-wild-ignore-table=mysql.%). This was already the behaviour for GRANT/REVOKE, I'm extending it to SET PASSWORD because it seems very logical (the contrary seems illogical). 2 new tests: - one to test if GRANT and SET PASSWORD are replicated - one to test if they are not replicated if replicate-wild-ignore-table=mysql.% The 2nd is also a testcase for BUG#980. --- mysql-test/r/rpl_do_grant.result | 26 +++++++++++ mysql-test/r/rpl_ignore_grant.result | 37 ++++++++++++++++ mysql-test/t/rpl_do_grant.test | 46 ++++++++++++++++++++ mysql-test/t/rpl_ignore_grant-slave.opt | 1 + mysql-test/t/rpl_ignore_grant.test | 57 +++++++++++++++++++++++++ sql/sql_acl.cc | 19 +++++++++ 6 files changed, 186 insertions(+) create mode 100644 mysql-test/r/rpl_do_grant.result create mode 100644 mysql-test/r/rpl_ignore_grant.result create mode 100644 mysql-test/t/rpl_do_grant.test create mode 100644 mysql-test/t/rpl_ignore_grant-slave.opt create mode 100644 mysql-test/t/rpl_ignore_grant.test diff --git a/mysql-test/r/rpl_do_grant.result b/mysql-test/r/rpl_do_grant.result new file mode 100644 index 00000000000..fec935ae7ac --- /dev/null +++ b/mysql-test/r/rpl_do_grant.result @@ -0,0 +1,26 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +delete from mysql.user where user='rpl_do_grant'; +delete from mysql.db where user='rpl_do_grant'; +flush privileges; +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; +grant select on *.* to rpl_do_grant@localhost; +grant drop on test.* to rpl_do_grant@localhost; +show grants for rpl_do_grant@localhost; +Grants for rpl_do_grant@localhost +GRANT SELECT ON *.* TO 'rpl_do_grant'@'localhost' +GRANT DROP ON `test`.* TO 'rpl_do_grant'@'localhost' +set password for rpl_do_grant@localhost=password("does it work?"); +select password<>'' from mysql.user where user='rpl_do_grant'; +password<>'' +1 +delete from mysql.user where user='rpl_do_grant'; +delete from mysql.db where user='rpl_do_grant'; +flush privileges; +flush privileges; diff --git a/mysql-test/r/rpl_ignore_grant.result b/mysql-test/r/rpl_ignore_grant.result new file mode 100644 index 00000000000..6cd7d5b4c00 --- /dev/null +++ b/mysql-test/r/rpl_ignore_grant.result @@ -0,0 +1,37 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; +grant select on *.* to rpl_ignore_grant@localhost; +grant drop on test.* to rpl_ignore_grant@localhost; +show grants for rpl_ignore_grant@localhost; +Grants for rpl_ignore_grant@localhost +GRANT SELECT ON *.* TO 'rpl_ignore_grant'@'localhost' +GRANT DROP ON `test`.* TO 'rpl_ignore_grant'@'localhost' +show grants for rpl_ignore_grant@localhost; +There is no such grant defined for user 'rpl_ignore_grant' on host 'localhost' +select count(*) from mysql.user where user='rpl_ignore_grant'; +count(*) +0 +select count(*) from mysql.db where user='rpl_ignore_grant'; +count(*) +0 +grant select on *.* to rpl_ignore_grant@localhost; +set password for rpl_ignore_grant@localhost=password("does it work?"); +select password<>'' from mysql.user where user='rpl_ignore_grant'; +password<>'' +0 +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; diff --git a/mysql-test/t/rpl_do_grant.test b/mysql-test/t/rpl_do_grant.test new file mode 100644 index 00000000000..89ff1afb5c9 --- /dev/null +++ b/mysql-test/t/rpl_do_grant.test @@ -0,0 +1,46 @@ +# Test that GRANT and SET PASSWORD are replicated to the slave + +source include/master-slave.inc; + +# do not be influenced by other tests. +connection master; +delete from mysql.user where user='rpl_do_grant'; +delete from mysql.db where user='rpl_do_grant'; +flush privileges; +save_master_pos; +connection slave; +sync_with_master; +# if these DELETE did nothing on the master, we need to do them manually on the +# slave. +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; + +# test replication of GRANT +connection master; +grant select on *.* to rpl_do_grant@localhost; +grant drop on test.* to rpl_do_grant@localhost; +save_master_pos; +connection slave; +sync_with_master; +show grants for rpl_do_grant@localhost; + +# test replication of SET PASSWORD +connection master; +set password for rpl_do_grant@localhost=password("does it work?"); +save_master_pos; +connection slave; +sync_with_master; +select password<>'' from mysql.user where user='rpl_do_grant'; + +# clear what we have done, to not influence other tests. +connection master; +delete from mysql.user where user='rpl_do_grant'; +delete from mysql.db where user='rpl_do_grant'; +flush privileges; +save_master_pos; +connection slave; +sync_with_master; +# no need to delete manually, as the DELETEs must have done some real job on +# master (updated binlog) +flush privileges; diff --git a/mysql-test/t/rpl_ignore_grant-slave.opt b/mysql-test/t/rpl_ignore_grant-slave.opt new file mode 100644 index 00000000000..e931bfbd37e --- /dev/null +++ b/mysql-test/t/rpl_ignore_grant-slave.opt @@ -0,0 +1 @@ +--replicate-wild-ignore-table=mysql.% diff --git a/mysql-test/t/rpl_ignore_grant.test b/mysql-test/t/rpl_ignore_grant.test new file mode 100644 index 00000000000..2fd7f186b3e --- /dev/null +++ b/mysql-test/t/rpl_ignore_grant.test @@ -0,0 +1,57 @@ +# Test that GRANT is not replicated to the slave +# when --replicate-wild-ignore-table=mysql.% +# In BUG#980, this test would _randomly_ fail. + +source include/master-slave.inc; + +# do not be influenced by other tests. +connection master; +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; +save_master_pos; +connection slave; +sync_with_master; +# as these DELETE were not replicated, we need to do them manually on the +# slave. +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; + +# test non-replication of GRANT +connection master; +grant select on *.* to rpl_ignore_grant@localhost; +grant drop on test.* to rpl_ignore_grant@localhost; +show grants for rpl_ignore_grant@localhost; +save_master_pos; +connection slave; +sync_with_master; +--error 1141 #("no such grant for user") +show grants for rpl_ignore_grant@localhost; +# check it another way +select count(*) from mysql.user where user='rpl_ignore_grant'; +select count(*) from mysql.db where user='rpl_ignore_grant'; + +# test non-replication of SET PASSWORD +# first force creation of the user on slave (because as the user does not exist +# on slave, the SET PASSWORD may be replicated but silently do nothing; this is +# not what we want; we want it to be not-replicated). +grant select on *.* to rpl_ignore_grant@localhost; +connection master; +set password for rpl_ignore_grant@localhost=password("does it work?"); +save_master_pos; +connection slave; +sync_with_master; +select password<>'' from mysql.user where user='rpl_ignore_grant'; + +# clear what we have done, to not influence other tests. +connection master; +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; +save_master_pos; +connection slave; +sync_with_master; +delete from mysql.user where user='rpl_ignore_grant'; +delete from mysql.db where user='rpl_ignore_grant'; +flush privileges; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fd7ea5aac51..3a3de2abf10 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1233,6 +1233,25 @@ static bool update_user_table(THD *thd, const char *host, const char *user, bzero((char*) &tables,sizeof(tables)); tables.alias=tables.real_name=(char*) "user"; tables.db=(char*) "mysql"; +#ifdef HAVE_REPLICATION + /* + GRANT and REVOKE are applied the slave in/exclusion rules as they are + some kind of updates to the mysql.% tables. + */ + if (thd->slave_thread && table_rules_on) + { + /* + The tables must be marked "updating" so that tables_ok() takes them into + account in tests. + */ + tables.updating=1; + /* Thanks to bzero, tables.next==0 */ + if (!tables_ok(0, &tables)) + DBUG_RETURN(0); + tables.updating=0; + } +#endif + if (!(table=open_ltable(thd,&tables,TL_WRITE))) DBUG_RETURN(1); /* purecov: deadcode */ table->field[0]->store(host,(uint) strlen(host)); From 9724a2590127891b503ed8e5abc4dcd6ddad1ccc Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Sun, 3 Aug 2003 16:33:04 +0300 Subject: [PATCH 217/237] Cleaned up code comment --- sql/item_strfunc.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 9e37a5a18e5..ff01d841e78 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1094,7 +1094,8 @@ String *Item_func_database::val_str(String *str) String *Item_func_user::val_str(String *str) { THD *thd=current_thd; - if (!(thd->user) || // for system threads (e.g. replication thread) + // For a replication thread user may be a null pointer (To be fixed) + if (!thd->user || str->copy((const char*) thd->user,(uint) strlen(thd->user)) || str->append('@') || str->append(thd->host ? thd->host : thd->ip ? thd->ip : "")) From bb12d905cb75a813bfed1bc05c82c02e91762b59 Mon Sep 17 00:00:00 2001 From: "guilhem@mysql.com" <> Date: Mon, 4 Aug 2003 10:59:44 +0200 Subject: [PATCH 218/237] 2 bugfixes: - Bug #985: "Between RESET SLAVE and START SLAVE, SHOW SLAVE STATUS is wrong." Now RESET SLAVE puts correct info in mi->host etc. A new test rpl_reset_slave for that. - Bug #986: "CHANGE MASTER & START SLAVE do not reset error columns in SHOW SLAVE STATUS". Now these reset the errors. --- mysql-test/r/rpl_loaddata.result | 26 ++++++++++++++ mysql-test/r/rpl_reset_slave.result | 22 ++++++++++++ mysql-test/t/rpl_loaddata.test | 53 +++++++++++++++++++++++++++++ mysql-test/t/rpl_reset_slave.test | 26 ++++++++++++++ sql/slave.cc | 40 ++++++++++++++++------ sql/slave.h | 2 ++ sql/sql_repl.cc | 17 +++++---- 7 files changed, 169 insertions(+), 17 deletions(-) create mode 100644 mysql-test/r/rpl_reset_slave.result create mode 100644 mysql-test/t/rpl_reset_slave.test diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index b5154ca95cf..05bdad0fb84 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -25,3 +25,29 @@ drop table t3; create table t1(a int, b int, unique(b)); insert into t1 values(1,10); load data infile '../../std_data/rpl_loaddata.dat' into table t1; +set global sql_slave_skip_counter=1; +start slave; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root MASTER_PORT 1 master-bin.001 1311 slave-relay-bin.002 1352 master-bin.001 Yes Yes 0 0 1311 1352 +set sql_log_bin=0; +delete from t1; +set sql_log_bin=1; +load data infile '../../std_data/rpl_loaddata.dat' into table t1; +stop slave; +change master to master_user='test'; +change master to master_user='root'; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root MASTER_PORT 1 master-bin.001 1442 slave-relay-bin.001 4 master-bin.001 No No 0 0 1442 4 +set global sql_slave_skip_counter=1; +start slave; +set sql_log_bin=0; +delete from t1; +set sql_log_bin=1; +load data infile '../../std_data/rpl_loaddata.dat' into table t1; +stop slave; +reset slave; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4 diff --git a/mysql-test/r/rpl_reset_slave.result b/mysql-test/r/rpl_reset_slave.result new file mode 100644 index 00000000000..c1bc1e8e483 --- /dev/null +++ b/mysql-test/r/rpl_reset_slave.result @@ -0,0 +1,22 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120 +stop slave; +change master to master_user='test'; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 test MASTER_PORT 1 master-bin.001 79 slave-relay-bin.001 4 master-bin.001 No No 0 0 79 4 +reset slave; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4 +start slave; +show slave status; +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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120 diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test index 96a4eb3fb76..0a07dd7549b 100644 --- a/mysql-test/t/rpl_loaddata.test +++ b/mysql-test/t/rpl_loaddata.test @@ -6,6 +6,9 @@ # # check if duplicate entries trigger an error (they should unless IGNORE or # REPLACE was used on the master) (bug 571). +# +# check if START SLAVE, RESET SLAVE, CHANGE MASTER reset Last_slave_error and +# Last_slave_errno in SHOW SLAVE STATUS (1st and 3rd commands did not: bug 986). source include/master-slave.inc; @@ -44,3 +47,53 @@ save_master_pos; connection slave; # The SQL slave thread should be stopped now. wait_for_slave_to_stop; + +# Skip the bad event and see if error is cleared in SHOW SLAVE STATUS by START +# SLAVE, even though we are not executing any event (as sql_slave_skip_counter +# takes us directly to the end of the relay log). + +set global sql_slave_skip_counter=1; +start slave; +sync_with_master; +--replace_result $MASTER_MYPORT MASTER_PORT +show slave status; + +# Trigger error again to test CHANGE MASTER + +connection master; +set sql_log_bin=0; +delete from t1; +set sql_log_bin=1; +load data infile '../../std_data/rpl_loaddata.dat' into table t1; +save_master_pos; +connection slave; +# The SQL slave thread should be stopped now. +wait_for_slave_to_stop; + +# CHANGE MASTER and see if error is cleared in SHOW SLAVE STATUS. +stop slave; +change master to master_user='test'; +change master to master_user='root'; +--replace_result $MASTER_MYPORT MASTER_PORT +show slave status; + +# Trigger error again to test RESET SLAVE + +set global sql_slave_skip_counter=1; +start slave; +sync_with_master; +connection master; +set sql_log_bin=0; +delete from t1; +set sql_log_bin=1; +load data infile '../../std_data/rpl_loaddata.dat' into table t1; +save_master_pos; +connection slave; +# The SQL slave thread should be stopped now. +wait_for_slave_to_stop; + +# RESET SLAVE and see if error is cleared in SHOW SLAVE STATUS. +stop slave; +reset slave; +--replace_result $MASTER_MYPORT MASTER_PORT +show slave status; diff --git a/mysql-test/t/rpl_reset_slave.test b/mysql-test/t/rpl_reset_slave.test new file mode 100644 index 00000000000..9c58ac0c787 --- /dev/null +++ b/mysql-test/t/rpl_reset_slave.test @@ -0,0 +1,26 @@ +# See SHOW SLAVE STATUS displays well after RESET SLAVE (it should display the +# --master-* options from mysqld, as this is what is going to be used next time +# slave threads will be started). In bug 985, it displayed old values (of before +# RESET SLAVE). + +source include/master-slave.inc; +connection master; +save_master_pos; +connection slave; +sync_with_master; +--replace_result $MASTER_MYPORT MASTER_PORT +show slave status; + +stop slave; +change master to master_user='test'; +--replace_result $MASTER_MYPORT MASTER_PORT +show slave status; + +reset slave; +--replace_result $MASTER_MYPORT MASTER_PORT +show slave status; + +start slave; +sync_with_master; +--replace_result $MASTER_MYPORT MASTER_PORT +show slave status; diff --git a/sql/slave.cc b/sql/slave.cc index b4fa11f456e..7c7e1760169 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1476,6 +1476,27 @@ static int count_relay_log_space(RELAY_LOG_INFO* rli) DBUG_RETURN(0); } +void init_master_info_with_options(MASTER_INFO* mi) +{ + mi->master_log_name[0] = 0; + mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number + + if (master_host) + strmake(mi->host, master_host, sizeof(mi->host) - 1); + if (master_user) + strmake(mi->user, master_user, sizeof(mi->user) - 1); + if (master_password) + strmake(mi->password, master_password, HASH_PASSWORD_LENGTH); + mi->port = master_port; + mi->connect_retry = master_connect_retry; +} + +void clear_last_slave_error(RELAY_LOG_INFO* rli) +{ + //Clear the errors displayed by SHOW SLAVE STATUS + rli->last_slave_error[0]=0; + rli->last_slave_errno=0; +} int init_master_info(MASTER_INFO* mi, const char* master_info_fname, const char* slave_info_fname, @@ -1529,18 +1550,9 @@ file '%s')", fname); goto err; } - mi->master_log_name[0] = 0; - mi->master_log_pos = BIN_LOG_HEADER_SIZE; // skip magic number mi->fd = fd; - - if (master_host) - strmake(mi->host, master_host, sizeof(mi->host) - 1); - if (master_user) - strmake(mi->user, master_user, sizeof(mi->user) - 1); - if (master_password) - strmake(mi->password, master_password, HASH_PASSWORD_LENGTH); - mi->port = master_port; - mi->connect_retry = master_connect_retry; + init_master_info_with_options(mi); + } else // file exists { @@ -2611,6 +2623,12 @@ slave_begin: pthread_cond_broadcast(&rli->start_cond); // This should always be set to 0 when the slave thread is started rli->pending = 0; + /* + Reset errors for a clean start (otherwise, if the master is idle, the SQL + thread may execute no Query_log_event, so the error will remain even + though there's no problem anymore). + */ + clear_last_slave_error(rli); //tell the I/O thread to take relay_log_space_limit into account from now on pthread_mutex_lock(&rli->log_space_lock); diff --git a/sql/slave.h b/sql/slave.h index d1fd54d3c04..193b0ab9dd7 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -389,6 +389,8 @@ void skip_load_data_infile(NET* net); void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...); void end_slave(); /* clean up */ +void init_master_info_with_options(MASTER_INFO* mi); +void clear_last_slave_error(RELAY_LOG_INFO* rli); int init_master_info(MASTER_INFO* mi, const char* master_info_fname, const char* slave_info_fname, bool abort_if_no_master_info_file); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index faa18b146bb..cdd0bca4a0e 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -769,12 +769,15 @@ int reset_slave(THD *thd, MASTER_INFO* mi) &errmsg))) goto err; - //Clear master's log coordinates (only for good display of SHOW SLAVE STATUS) - mi->master_log_name[0]= 0; - mi->master_log_pos= BIN_LOG_HEADER_SIZE; - //Clear the errors displayed by SHOW SLAVE STATUS - mi->rli.last_slave_error[0]=0; - mi->rli.last_slave_errno=0; + /* + Clear master's log coordinates and reset host/user/etc to the values + specified in mysqld's options (only for good display of SHOW SLAVE STATUS; + next init_master_info() (in start_slave() for example) would have set them + the same way; but here this is for the case where the user does SHOW SLAVE + STATUS; before doing START SLAVE; + */ + init_master_info_with_options(mi); + clear_last_slave_error(&mi->rli); //close master_info_file, relay_log_info_file, set mi->inited=rli->inited=0 end_master_info(mi); //and delete these two files @@ -965,6 +968,8 @@ int change_master(THD* thd, MASTER_INFO* mi) pthread_mutex_lock(&mi->rli.data_lock); mi->rli.abort_pos_wait++; /* for MASTER_POS_WAIT() to abort */ + /* Clear the error, for a clean start. */ + clear_last_slave_error(&mi->rli); /* If we don't write new coordinates to disk now, then old will remain in relay-log.info until START SLAVE is issued; but if mysqld is shutdown From be123fe5a792ccbd147e44fc93aa48529dd80a81 Mon Sep 17 00:00:00 2001 From: "miguel@hegel.local" <> Date: Mon, 4 Aug 2003 09:44:26 -0300 Subject: [PATCH 219/237] Fix VC++ compiler error --- 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 b9e9c0a14fa..728810fcf7f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5333,7 +5333,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) Impossible range (for example lookup on NULL on not null field) Create empty result set */ - if (!(table->record_pointers= my_malloc(1, MYF(MY_WME)))) + if (!(table->record_pointers= (uchar*) my_malloc(1, MYF(MY_WME)))) goto err; table->found_records= 0; goto end; From c0317ce66c2c5e5c228a294a5fae45e1ebd1db61 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Tue, 5 Aug 2003 16:29:09 +0200 Subject: [PATCH 220/237] make it clear for optimizer that XOR's are not optimizable at the moment (BUG#992) --- mysql-test/r/func_test.result | 5 +++++ mysql-test/t/func_test.test | 5 +++++ sql/item_cmpfunc.h | 10 ++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result index 8cfae44b9dd..e1c27daa9a7 100644 --- a/mysql-test/r/func_test.result +++ b/mysql-test/r/func_test.result @@ -46,6 +46,11 @@ select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1; select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL; 1 XOR 1 1 XOR 0 0 XOR 1 0 XOR 0 NULL XOR 1 1 XOR NULL 0 XOR NULL 0 1 1 0 NULL NULL NULL +create table t1 (a int); +insert t1 values (1); +select * from t1 where 1 xor 1; +a +drop table t1; select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1; 5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1 0 1 diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test index f5ad2e21c73..700fab97f5e 100644 --- a/mysql-test/t/func_test.test +++ b/mysql-test/t/func_test.test @@ -18,6 +18,11 @@ select -1.49 or -1.49,0.6 or 0.6; select 3 ^ 11, 1 ^ 1, 1 ^ 0, 1 ^ NULL, NULL ^ 1; select 1 XOR 1, 1 XOR 0, 0 XOR 1, 0 XOR 0, NULL XOR 1, 1 XOR NULL, 0 XOR NULL; +create table t1 (a int); +insert t1 values (1); +select * from t1 where 1 xor 1; +drop table t1; + # # Wrong usage of functions # diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 536ac9dc3d4..58c7ea8d00d 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -28,7 +28,7 @@ public: Item_bool_func(Item *a) :Item_int_func(a) {} Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {} void fix_length_and_dec() { decimals=0; max_length=1; } - unsigned int size_of() { return sizeof(*this);} + unsigned int size_of() { return sizeof(*this);} }; class Item_bool_func2 :public Item_int_func @@ -595,7 +595,7 @@ public: void print(String *str); void split_sum_func(List &fields); friend int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); - unsigned int size_of() { return sizeof(*this);} + unsigned int size_of() { return sizeof(*this);} void top_level_item() { abort_on_null=1; } }; @@ -634,12 +634,18 @@ inline Item *and_conds(Item *a,Item *b) return cond; } +/* + XOR is Item_cond, not an Item_int_func bevause we could like to + optimize (a XOR b) later on. It's low prio, though +*/ class Item_cond_xor :public Item_cond { public: Item_cond_xor() :Item_cond() {} Item_cond_xor(Item *i1,Item *i2) :Item_cond(i1,i2) {} enum Functype functype() const { return COND_XOR_FUNC; } + /* TODO: remove the next line when implementing XOR optimization */ + enum Type type() const { return FUNC_ITEM; } longlong val_int(); const char *func_name() const { return "xor"; } }; From 27fde36d1512c4b74edca48d3361050bd226876e Mon Sep 17 00:00:00 2001 From: "miguel@hegel.local" <> Date: Tue, 5 Aug 2003 22:57:44 -0300 Subject: [PATCH 221/237] Fix an erronous cast for GCC introduced for to fix VC++ compiler error --- 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 728810fcf7f..1230dffcaa9 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -5333,7 +5333,7 @@ create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit) Impossible range (for example lookup on NULL on not null field) Create empty result set */ - if (!(table->record_pointers= (uchar*) my_malloc(1, MYF(MY_WME)))) + if (!(table->record_pointers= (byte*) my_malloc(1, MYF(MY_WME)))) goto err; table->found_records= 0; goto end; From b8e5f7f119c62001762cba2d62d68f0f8bae7af6 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 6 Aug 2003 11:42:48 +0200 Subject: [PATCH 222/237] Some fixes for the RPM spec file: - Fixed BUG#959 (libmysqld not being compiled properly) - Fixed BUG#998 (RPM build errors): added missing files to the distribution (mysql_fix_extensions, mysql_tableinfo, mysqldumpslow, mysql_fix_privilege_tables.1), removed "-n" from %install section. --- support-files/mysql.spec.sh | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 15127edeef4..0a33ae397e4 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -216,7 +216,6 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \ --infodir=%{_infodir} \ --includedir=%{_includedir} \ --mandir=%{_mandir} \ - --with-embedded-server \ --enable-thread-safe-client \ --with-comment=\"Official MySQL RPM\"; # Add this for more debugging support @@ -245,7 +244,7 @@ MBD=$RPM_BUILD_DIR/mysql-%{mysql_version} # Clean up the BuildRoot first [ "$RBR" != "/" ] && [ -d $RBR ] && rm -rf $RBR; -mkdir -p $RBR +mkdir -p $RBR%{_libdir}/mysql # # Use MYSQL_BUILD_PATH so that we can use a dedicated version of gcc @@ -267,6 +266,7 @@ BuildMySQL "--enable-shared \ --with-berkeley-db \ --with-innodb \ --with-raid \ + --with-embedded-server \ --with-server-suffix='-Max'" # Save everything for debug @@ -276,6 +276,9 @@ BuildMySQL "--enable-shared \ mv sql/mysqld sql/mysqld-max nm --numeric-sort sql/mysqld-max > sql/mysqld-max.sym +# Install embedded server library in the build root +install -m 644 libmysqld/libmysqld.a $RBR%{_libdir}/mysql + # Save libraries (cd libmysql/.libs; tar cf $RBR/shared-libs.tar *.so*) (cd libmysql_r/.libs; tar rf $RBR/shared-libs.tar *.so*) @@ -295,13 +298,14 @@ BuildMySQL "--disable-shared \ --with-client-ldflags='-all-static' \ $USE_OTHER_LIBC_DIR \ --with-server-suffix='%{server_suffix}' \ + --without-embedded-server \ --without-berkeley-db \ --with-innodb \ --without-vio \ --without-openssl" nm --numeric-sort sql/mysqld > sql/mysqld.sym -%install -n mysql-%{mysql_version} +%install RBR=$RPM_BUILD_ROOT MBD=$RPM_BUILD_DIR/mysql-%{mysql_version} @@ -319,7 +323,7 @@ install -d $RBR%{_sbindir} make install-strip DESTDIR=$RBR benchdir_root=%{_datadir} # Install shared libraries (Disable for architectures that don't support it) -(cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar) +(cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar; rm -f $RBR/shared-libs.tar) # install saved mysqld-max install -s -m755 $MBD/sql/mysqld-max $RBR%{_sbindir}/mysqld-max @@ -447,6 +451,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man1/isamlog.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_zap.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqld.1* +%doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqld_multi.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqld_safe.1* %doc %attr(644, root, man) %{_mandir}/man1/perror.1* @@ -462,6 +467,7 @@ fi %attr(755, root, root) %{_bindir}/myisampack %attr(755, root, root) %{_bindir}/mysql_convert_table_format %attr(755, root, root) %{_bindir}/mysql_explain_log +%attr(755, root, root) %{_bindir}/mysql_fix_extensions %attr(755, root, root) %{_bindir}/mysql_fix_privilege_tables %attr(755, root, root) %{_bindir}/mysql_install_db %attr(755, root, root) %{_bindir}/mysql_secure_installation @@ -492,12 +498,14 @@ fi %attr(755, root, root) %{_bindir}/msql2mysql %attr(755, root, root) %{_bindir}/mysql %attr(755, root, root) %{_bindir}/mysql_find_rows +%attr(755, root, root) %{_bindir}/mysql_tableinfo %attr(755, root, root) %{_bindir}/mysql_waitpid %attr(755, root, root) %{_bindir}/mysqlaccess %attr(755, root, root) %{_bindir}/mysqladmin %attr(755, root, root) %{_bindir}/mysqlbinlog %attr(755, root, root) %{_bindir}/mysqlcheck %attr(755, root, root) %{_bindir}/mysqldump +%attr(755, root, root) %{_bindir}/mysqldumpslow %attr(755, root, root) %{_bindir}/mysqlimport %attr(755, root, root) %{_bindir}/mysqlshow @@ -554,6 +562,13 @@ fi %attr(644, root, root) %{_libdir}/mysql/libmysqld.a %changelog +* Tue Aug 05 2003 Lenz Grimmer + +- Fixed BUG#959 (libmysqld not being compiled properly) +- Fixed BUG#998 (RPM build errors): added missing files to the + distribution (mysql_fix_extensions, mysql_tableinfo, mysqldumpslow, + mysql_fix_privilege_tables.1), removed "-n" from %install section. + * Wed Jul 09 2003 Lenz Grimmer - removed the GIF Icon (file was not included in the sources anyway) From 3d5d56cea9961971f7d72d9f7cd6c4ed66ed7bdb Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Wed, 6 Aug 2003 12:13:08 +0200 Subject: [PATCH 223/237] - try harder to obtain the FQDN with "hostname -f", if possible (BUG#897) Unfortunately the returned value of "hostname" is inconsistent on various platforms - some return the host name only, others return the FQDN by default. On Linux, one can use option "-f" to enable the output of the FQDN. Use it, if available. --- scripts/mysql_install_db.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 64fdd0dfebb..ffb857933cd 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -107,7 +107,13 @@ then fi fi -hostname=`@HOSTNAME@` # Install this too in the user table +# Try to determine the fully qualified domain name (FQDN) +HOSTNAME="@HOSTNAME@" +if $HOSTNAME -f > /dev/null 2>&1 ; then + hostname=`$HOSTNAME -f` +else + hostname=`$HOSTNAME` +fi # Check if hostname is valid if test "$IN_RPM" -eq 0 -a $force -eq 0 From 73bb79dbea335cd82f35ee610d01ca3d1d5a7527 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Wed, 6 Aug 2003 15:37:22 +0200 Subject: [PATCH 224/237] Bug #792 combination of date-interval and between with mixed constant and non-constant --- mysql-test/r/type_date.result | 2 ++ mysql-test/t/type_date.test | 1 + sql/item_timefunc.cc | 10 ++++------ 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index 214328eab47..8dfe14bc1a2 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -32,6 +32,8 @@ datum 2000-01-02 2000-01-03 2000-01-04 +SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY; +datum DROP TABLE t1; CREATE TABLE t1 ( user_id char(10), diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 68c2d55aac9..bd6d8c49c22 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -34,6 +34,7 @@ INSERT INTO t1 VALUES ( "2000-1-3" ); INSERT INTO t1 VALUES ( "2000-1-4" ); INSERT INTO t1 VALUES ( "2000-1-5" ); SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND "2000-1-4"; +SELECT * FROM t1 WHERE datum BETWEEN "2000-1-2" AND datum - INTERVAL 100 DAY; DROP TABLE t1; # diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 84e7a44ac61..caea79314de 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1058,14 +1058,12 @@ String *Item_date_add_interval::val_str(String *str) longlong Item_date_add_interval::val_int() { TIME ltime; + longlong date; if (Item_date_add_interval::get_date(<ime,0)) return (longlong) 0; - return ((longlong) (((ulong) ltime.year)*10000L+ - (((uint) ltime.month)*100+ - (uint) ltime.day))*(longlong) 1000000L+ - (longlong) ((ulong) ((uint) ltime.hour)*10000L+ - (ulong) (((uint)ltime.minute)*100L+ - (uint) ltime.second))); + date = (ltime.year*100L + ltime.month)*100L + ltime.day; + return ltime.time_type == TIMESTAMP_DATE ? date : + ((date*100L + ltime.hour)*100L+ ltime.minute)*100L + ltime.second; } void Item_extract::fix_length_and_dec() From d527253d04da2c6b0b778732b9d1c4917335672e Mon Sep 17 00:00:00 2001 From: "greg@gcw.ath.cx" <> Date: Wed, 6 Aug 2003 22:57:14 -0400 Subject: [PATCH 225/237] Copied Venu's make_win_src_distribution script from 4.1 tree --- scripts/Makefile.am | 1 + scripts/make_win_src_distribution.sh | 404 +++++++++++++++++++++++++++ 2 files changed, 405 insertions(+) create mode 100755 scripts/make_win_src_distribution.sh diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 8f17d8519b8..f1ca6023fbe 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -35,6 +35,7 @@ bin_SCRIPTS = @server_scripts@ \ mysqld_multi EXTRA_SCRIPTS = make_binary_distribution.sh \ + make_win_src_distribution.sh \ msql2mysql.sh \ mysql_config.sh \ mysql_fix_privilege_tables.sh \ diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh new file mode 100755 index 00000000000..d2b50e06f54 --- /dev/null +++ b/scripts/make_win_src_distribution.sh @@ -0,0 +1,404 @@ +#!/bin/sh + +# +# Script to create a Windows src package +# + +version=@VERSION@ +export version +SOURCE=`pwd` +CP="cp -p" + +DEBUG=0 +SILENT=0 +SUFFIX="" +DIRNAME="" +OUTTAR=0 + +# +# This script must run from MySQL top directory +# + +if [ ! -f scripts/make_win_src_distribution ]; then + echo "ERROR : You must run this script from the MySQL top-level directory" + exit 1 +fi + +# +# Check for source compilation/configuration +# + +if [ ! -f sql/sql_yacc.cc ]; then + echo "ERROR : Sorry, you must run this script after the complete build," + echo " hope you know what you are trying to do !!" + exit 1 +fi + +# +# Debug print of the status +# + +print_debug() +{ + for statement + do + if [ "$DEBUG" = "1" ] ; then + echo $statement + fi + done +} + +# +# Usage of the script +# + +show_usage() +{ + echo "MySQL utility script to create a Windows src package, and it takes" + echo "the following arguments:" + echo "" + echo " --debug Debug, without creating the package" + echo " --tmp Specify the temporary location" + echo " --suffix Suffix name for the package" + echo " --dirname Directory name to copy files (intermediate)" + echo " --silent Do not list verbosely files processed" + echo " --tar Create tar.gz package instead of .zip" + echo " --help Show this help message" + + exit 0 +} + +# +# Parse the input arguments +# + +parse_arguments() { + for arg do + case "$arg" in + --debug) DEBUG=1;; + --tmp=*) TMP=`echo "$arg" | sed -e "s;--tmp=;;"` ;; + --suffix=*) SUFFIX=`echo "$arg" | sed -e "s;--suffix=;;"` ;; + --dirname=*) DIRNAME=`echo "$arg" | sed -e "s;--dirname=;;"` ;; + --silent) SILENT=1 ;; + --tar) OUTTAR=1 ;; + --help) show_usage ;; + *) + echo "Unknown argument '$arg'" + exit 1 + ;; + esac + done +} + +parse_arguments "$@" + +# +# Assign the tmp directory if it was set from the environment variables +# + +for i in $TMP $TMPDIR $TEMPDIR $TEMP /tmp +do + if [ "$i" ]; then + print_debug "Setting TMP to '$i'" + TMP=$i + break + fi +done + + +# + +# +# Create a tmp dest directory to copy files +# + +BASE=$TMP/my_win_dist$SUFFIX + +if [ -d $BASE ] ; then + print_debug "Destination directory '$BASE' already exists, deleting it" + rm -r -f $BASE +fi + +$CP -r $SOURCE/VC++Files $BASE +( +find $BASE \( -name "*.dsp" -o -name "*.dsw" \) -and -not -path \*SCCS\* -print +)|( + while read v + do + print_debug "Replacing LF -> CRLF from '$v'" + + # ^M -> type CTRL V + CTRL M + cat $v | sed 's/ +//' | sed 's/$/ +/' > $v.tmp + rm $v + mv $v.tmp $v + done +) + +# +# Move all error message files to root directory +# + +$CP -r $SOURCE/sql/share $BASE/ +rm -r -f "$BASE/share/Makefile" +rm -r -f "$BASE/share/Makefile.in" +rm -r -f "$BASE/share/Makefile.am" + +# +# Clean up if we did this from a bk tree +# + +if [ -d $BASE/SCCS ] +then + find $BASE/ -type d -name SCCS -printf " \"%p\"" | xargs rm -r -f +fi + +mkdir $BASE/Docs $BASE/extra $BASE/include + + +# +# Copy directory files +# + +copy_dir_files() +{ + for arg do + print_debug "Copying files from directory '$arg'" + cd $SOURCE/$arg + if [ ! -d $BASE/$arg ]; then + print_debug "Creating directory '$arg'" + mkdir $BASE/$arg + fi + for i in *.c *.cpp *.h *.ih *.i *.ic *.asm *.def \ + README INSTALL* LICENSE + do + if [ -f $i ] + then + $CP $SOURCE/$arg/$i $BASE/$arg/$i + fi + done + for i in *.cc + do + if [ -f $i ] + then + i=`echo $i | sed 's/.cc$//g'` + $CP $SOURCE/$arg/$i.cc $BASE/$arg/$i.cpp + fi + done + done +} + +# +# Copy directory contents recursively +# + +copy_dir_dirs() { + + for arg do + + basedir=$arg + + if [ ! -d $BASE/$arg ]; then + mkdir $BASE/$arg + fi + + copy_dir_files $arg + + cd $SOURCE/$arg/ + for i in * + do + if [ -d $SOURCE/$basedir/$i ] && [ "$i" != "SCCS" ]; then + copy_dir_files $basedir/$i + fi + done + done +} + +# +# Input directories to be copied +# + +for i in client dbug extra heap include isam \ + libmysql libmysqld merge myisam \ + myisammrg mysys regex sql strings \ + vio zlib +do + copy_dir_files $i +done + +# +# Input directories to be copied recursively +# + +for i in bdb innobase +do + copy_dir_dirs $i +done + +# +# Create dummy innobase configure header +# + +if [ -f $BASE/innobase/ib_config.h ]; then + rm -f $BASE/innobase/ib_config.h +fi +touch $BASE/innobase/ib_config.h + + +# +# Copy miscellaneous files +# + +cd $SOURCE +for i in COPYING ChangeLog README \ + INSTALL-SOURCE INSTALL-WIN \ + INSTALL-WIN-SOURCE \ + Docs/manual_toc.html Docs/manual.html \ + Docs/mysqld_error.txt Docs/INSTALL-BINARY + +do + print_debug "Copying file '$i'" + if [ -f $i ] + then + $CP $i $BASE/$i + fi +done + +# +# Fix some windows files +# + +./extra/replace std:: "" -- $BASE/sql/sql_yacc.cpp + +# +# Initialize the initial data directory +# + +if [ -f scripts/mysql_install_db ]; then + print_debug "Initializing the 'data' directory" + scripts/mysql_install_db --no-defaults --windows --datadir=$BASE/data +fi + +# +# Specify the distribution package name and copy it +# + +if test -z $DIRNAME +then + NEW_DIR_NAME=mysql@MYSQL_SERVER_SUFFIX@-$version$SUFFIX +else + NEW_DIR_NAME=$DIRNAME +fi +NEW_NAME=$NEW_DIR_NAME-win-src + +BASE2=$TMP/$NEW_DIR_NAME +rm -r -f $BASE2 +mv $BASE $BASE2 +BASE=$BASE2 + +# +# If debugging, don't create a zip/tar/gz +# + +if [ "$DEBUG" = "1" ] ; then + echo "Please check the distribution files from $BASE" + echo "Exiting (without creating the package).." + exit +fi + +# +# This is needed to prefere gnu tar instead of tar because tar can't +# always handle long filenames +# + +PATH_DIRS=`echo $PATH | sed -e 's/^:/. /' -e 's/:$/ ./' -e 's/::/ . /g' -e 's/:/ /g' ` +which_1 () +{ + for cmd + do + for d in $PATH_DIRS + do + for file in $d/$cmd + do + if test -x $file -a ! -d $file + then + echo $file + exit 0 + fi + done + done + done + exit 1 +} + +# +# Create the result zip/tar file +# + +set_tarzip_options() +{ + for arg + do + if [ "$arg" = "tar" ]; then + ZIPFILE1=gnutar + ZIPFILE2=gtar + OPT=cvf + EXT=".tar" + NEED_COMPRESS=1 + if [ "$SILENT" = "1" ] ; then + OPT=cf + fi + else + ZIPFILE1=zip + ZIPFILE2="" + OPT="-r" + EXT=".zip" + NEED_COMPRESS=0 + if [ "$SILENT" = "1" ] ; then + OPT="$OPT -q" + fi + fi + done +} + +if [ "$OUTTAR" = "1" ]; then + set_tarzip_options 'tar' +else + set_tarzip_options 'zip' +fi + +tar=`which_1 $ZIPFILE1 $ZIPFILE2` +if test "$?" = "1" -o "$tar" = "" +then + print_debug "Search failed for '$ZIPFILE1', '$ZIPFILE2', using default 'tar'" + tar=tar + set_tarzip_options 'tar' +fi + +# +# Create the archive +# + +print_debug "Using $tar to create archive" + +cd $TMP + +rm -f $SOURCE/$NEW_NAME$EXT +$tar $OPT $SOURCE/$NEW_NAME$EXT $NEW_DIR_NAME +cd $SOURCE + +if [ "$NEED_COMPRESS" = "1" ] +then + print_debug "Compressing archive" + gzip -9 $NEW_NAME$EXT + EXT="$EXT.gz" +fi + +print_debug "Removing temporary directory" +rm -r -f $BASE + +if [ "$SILENT" = "0" ] ; then + echo "$NEW_NAME$EXT created successfully !!" +fi +# End of script From e177eba89b552516138b5ae69fb054ccb4cb94bd Mon Sep 17 00:00:00 2001 From: "greg@gcw.ath.cx" <> Date: Thu, 7 Aug 2003 01:14:45 -0400 Subject: [PATCH 226/237] New option for Bootstrap: -w | --win-dist to create Windows source package --- Build-tools/Bootstrap | 23 ++++++++++++++++++++--- scripts/Makefile.am | 1 + 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index 20cd5a089bd..15dfb31dfdd 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -43,6 +43,7 @@ $opt_suffix= ""; $opt_test= undef; $opt_skip_check= undef; $opt_skip_manual= undef; +$opt_win_dist= undef; $version= "unknown"; $major=$minor=$release=0; @@ -62,7 +63,8 @@ GetOptions( "skip-manual", "suffix=s", "test|t", - "verbose|v" + "verbose|v", + "win-dist|w" ) || print_help(""); # @@ -303,7 +305,21 @@ $command= "make dist"; &run_command($command, "make dist failed!"); # -# Run "make distcheck" to verify the source archive +# Package the Windows source +# +if ($opt_win_dist) +{ + &logger ("Creating Windows source package"); + chdir("scripts"); + $command= "make make_win_src_distribution"; + &run_command($command, "make make_win_src_distribution failed!"); + chdir(".."); + $command= "./scripts/make_win_src_distibution"; + &run_command($command, "make_win_src_distribution failed!"); +} + +# +# Run "make distcheck" to verify the source archive # if (!$opt_skip_check) { @@ -330,7 +346,7 @@ sub print_help print "ERROR: $message\n"; } print < Checks out (exports) a clear-text version of the given local BitKeeper @@ -376,6 +392,7 @@ Options: (e.g. "-20020518"). -t, --test Run the test suite after build -v, --verbose Be verbose +-w, --win-dist Also make Windows source distribution Example: diff --git a/scripts/Makefile.am b/scripts/Makefile.am index f1ca6023fbe..d6f59cb1ae9 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -65,6 +65,7 @@ pkgdata_DATA = make_binary_distribution # failures with it. CLEANFILES = @server_scripts@ \ make_binary_distribution \ + make_win_src_distribution \ msql2mysql \ mysql_config \ mysql_fix_privilege_tables \ From 4235268bef661c9095f4034a7f409daf711c9a35 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Thu, 7 Aug 2003 11:16:34 +0200 Subject: [PATCH 227/237] fixed password buffer overflow --- sql/sql_acl.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f36e39b0645..554417322a4 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -206,10 +206,10 @@ int acl_init(bool dont_read_acl_tables) "Found old style password for user '%s'. Ignoring user. (You may want to restart using --old-protocol)", user.user ? user.user : ""); /* purecov: tested */ } - else if (length % 8) // This holds true for passwords + else if (length % 8 || length > 16) { sql_print_error( - "Found invalid password for user: '%s@%s'; Ignoring user", + "Found invalid password for user: '%s'@'%s'; Ignoring user", user.user ? user.user : "", user.host.hostname ? user.host.hostname : ""); /* purecov: tested */ continue; /* purecov: tested */ From 7da378f1d1f4acf9cd22ead124c3eab666d886b3 Mon Sep 17 00:00:00 2001 From: "serg@serg.mylan" <> Date: Thu, 7 Aug 2003 13:39:53 +0200 Subject: [PATCH 228/237] PRIMARY KEY can erroneously have HA_NULL_PART_KEY flag that breaks correct key sorting --- sql/sql_table.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index cf430aec35d..c55015f7aa5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -602,13 +602,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, sql_field->flags|= NOT_NULL_FLAG; sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL; } + else + key_info->flags|= HA_NULL_PART_KEY; if (!(file->table_flags() & HA_NULL_KEY)) { my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX), MYF(0),column->field_name); DBUG_RETURN(-1); } - key_info->flags|= HA_NULL_PART_KEY; } if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) { From d5547ad13bc1a0b74bb137039c78431efb606bf0 Mon Sep 17 00:00:00 2001 From: "lenz@mysql.com" <> Date: Thu, 7 Aug 2003 18:54:59 +0200 Subject: [PATCH 229/237] - some fixed for make_win_src_distribution to work properly --- Build-tools/Bootstrap | 4 ---- scripts/Makefile.am | 1 + scripts/make_win_src_distribution.sh | 36 +++++++++++++--------------- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/Build-tools/Bootstrap b/Build-tools/Bootstrap index 15dfb31dfdd..33eca958ae0 100755 --- a/Build-tools/Bootstrap +++ b/Build-tools/Bootstrap @@ -310,10 +310,6 @@ $command= "make dist"; if ($opt_win_dist) { &logger ("Creating Windows source package"); - chdir("scripts"); - $command= "make make_win_src_distribution"; - &run_command($command, "make make_win_src_distribution failed!"); - chdir(".."); $command= "./scripts/make_win_src_distibution"; &run_command($command, "make_win_src_distribution failed!"); } diff --git a/scripts/Makefile.am b/scripts/Makefile.am index d6f59cb1ae9..72fc73ef28b 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -17,6 +17,7 @@ ## Process this file with automake to create Makefile.in bin_SCRIPTS = @server_scripts@ \ + make_win_src_distribution \ msql2mysql \ mysql_config \ mysql_fix_privilege_tables \ diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh index d2b50e06f54..8f8ee344e93 100755 --- a/scripts/make_win_src_distribution.sh +++ b/scripts/make_win_src_distribution.sh @@ -38,9 +38,9 @@ fi # Debug print of the status # -print_debug() +print_debug() { - for statement + for statement do if [ "$DEBUG" = "1" ] ; then echo $statement @@ -52,7 +52,7 @@ print_debug() # Usage of the script # -show_usage() +show_usage() { echo "MySQL utility script to create a Windows src package, and it takes" echo "the following arguments:" @@ -98,14 +98,14 @@ parse_arguments "$@" for i in $TMP $TMPDIR $TEMPDIR $TEMP /tmp do - if [ "$i" ]; then + if [ "$i" ]; then print_debug "Setting TMP to '$i'" - TMP=$i + TMP=$i break fi done - + # # @@ -123,14 +123,12 @@ $CP -r $SOURCE/VC++Files $BASE ( find $BASE \( -name "*.dsp" -o -name "*.dsw" \) -and -not -path \*SCCS\* -print )|( - while read v + while read v do print_debug "Replacing LF -> CRLF from '$v'" - # ^M -> type CTRL V + CTRL M - cat $v | sed 's/ -//' | sed 's/$/ -/' > $v.tmp + # ^M -> type CTRL V + CTRL M + cat $v | sed 's/ //' | sed 's/$/ /' > $v.tmp rm $v mv $v.tmp $v done @@ -149,7 +147,7 @@ rm -r -f "$BASE/share/Makefile.am" # Clean up if we did this from a bk tree # -if [ -d $BASE/SCCS ] +if [ -d $BASE/SCCS ] then find $BASE/ -type d -name SCCS -printf " \"%p\"" | xargs rm -r -f fi @@ -171,9 +169,9 @@ copy_dir_files() mkdir $BASE/$arg fi for i in *.c *.cpp *.h *.ih *.i *.ic *.asm *.def \ - README INSTALL* LICENSE - do - if [ -f $i ] + README INSTALL* LICENSE + do + if [ -f $i ] then $CP $SOURCE/$arg/$i $BASE/$arg/$i fi @@ -198,14 +196,14 @@ copy_dir_dirs() { for arg do basedir=$arg - + if [ ! -d $BASE/$arg ]; then mkdir $BASE/$arg fi - + copy_dir_files $arg - - cd $SOURCE/$arg/ + + cd $SOURCE/$arg/ for i in * do if [ -d $SOURCE/$basedir/$i ] && [ "$i" != "SCCS" ]; then From 8f08c511ee781a99b63a74957ecb8547ac334f06 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Thu, 7 Aug 2003 20:16:37 +0300 Subject: [PATCH 230/237] Review of changesets since last pull. (Mostly code cleanups) --- include/my_sys.h | 1 - myisam/mi_check.c | 2 + mysql-test/t/rpl_insert_id.test | 1 + mysys/mf_format.c | 10 +---- sql/log_event.cc | 79 +++++++++++++++++---------------- sql/mini_client.cc | 2 +- sql/mysqld.cc | 64 +++++++++++++++++--------- sql/slave.cc | 38 ++++++++-------- sql/slave.h | 4 +- sql/sql_acl.cc | 11 ++--- vio/viosslfactories.c | 2 +- 11 files changed, 114 insertions(+), 100 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index acce118c7b8..7f8b8a80a1c 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -100,7 +100,6 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_RETURN_REAL_PATH 32 /* return full path for file */ #define MY_SAFE_PATH 64 /* Return NULL if too long path */ #define MY_RELATIVE_PATH 128 /* name is relative to 'dir' */ -#define MY_QUOTE_SPACES 256 /* quote when the path has spaces */ /* My seek flags */ #define MY_SEEK_SET 0 diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 4b28a88fc6e..0d7d7fae628 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -3563,11 +3563,13 @@ int update_state_info(MI_CHECK *param, MI_INFO *info,uint update) share->state.rec_per_key_rows=info->state->records; share->state.changed&= ~STATE_NOT_ANALYZED; if (info->state->records) + { for (i=0; istate.rec_per_key_part[i]=param->rec_per_key_part[i])) share->state.changed|= STATE_NOT_ANALYZED; } + } } if (update & (UPDATE_STAT | UPDATE_SORT | UPDATE_TIME | UPDATE_AUTO_INC)) { diff --git a/mysql-test/t/rpl_insert_id.test b/mysql-test/t/rpl_insert_id.test index d91bd02883e..49fefae72b8 100644 --- a/mysql-test/t/rpl_insert_id.test +++ b/mysql-test/t/rpl_insert_id.test @@ -4,6 +4,7 @@ # We also check how the foreign_key_check variable is replicated source include/master-slave.inc; +source include/have_innodb.inc connection master; drop table if exists t1; create table t1(a int auto_increment, key(a)); diff --git a/mysys/mf_format.c b/mysys/mf_format.c index 36d3908d310..937904847ee 100644 --- a/mysys/mf_format.c +++ b/mysys/mf_format.c @@ -111,15 +111,7 @@ my_string fn_format(my_string to, const char *name, const char *dir, strmov(buff,to); (void) my_readlink(to, buff, MYF(0)); } - if ( flag & MY_QUOTE_SPACES) - if ( strchr(to, ' ')) - { - char tmp_buff[FN_REFLEN]; - tmp_buff[0]='"'; - strxmov(tmp_buff+1,to,"\"",NullS); - strmov(to,tmp_buff); - } - DBUG_RETURN (to); + DBUG_RETURN(to); } /* fn_format */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 96bcf0a2779..f7955be3b09 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -593,8 +593,9 @@ err: UNLOCK_MUTEX; if (error) { - sql_print_error("Error in Log_event::read_log_event(): '%s', \ -data_len=%d,event_type=%d",error,data_len,head[EVENT_TYPE_OFFSET]); + sql_print_error("\ +Error in Log_event::read_log_event(): '%s', data_len: %d, event_type: %d", + error,data_len,head[EVENT_TYPE_OFFSET]); my_free(buf, MYF(MY_ALLOW_ZERO_PTR)); /* The SQL slave thread will check if file->error<0 to know @@ -1433,8 +1434,8 @@ void Slave_log_event::print(FILE* file, bool short_form, char* last_db) return; print_header(file); fputc('\n', file); - fprintf(file, "Slave: master_host: '%s' master_port: %d \ -master_log: '%s' master_pos: %s\n", + fprintf(file, "\ +Slave: master_host: '%s' master_port: %d master_log: '%s' master_pos: %s\n", master_host, master_port, master_log, llstr(master_pos, llbuff)); } @@ -1755,7 +1756,7 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) { int expected_error, actual_error= 0; init_sql_alloc(&thd->mem_root, 8192,0); - thd->db = rewrite_db((char*)db); + thd->db= (char*) rewrite_db(db); /* InnoDB internally stores the master log position it has processed so far; @@ -1811,15 +1812,16 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) !ignored_error_code(expected_error)) { slave_print_error(rli, 0, - "Query '%s' did not get the same error as the query \ -got on master - got on master: '%s' (%d), got on slave: '%s' (%d) \ -(default database was '%s')", + "\ +Query '%s' caused different errors on master and slave. \ +Error on master: '%s' (%d), Error on slave: '%s' (%d). \ +Default database: '%s'", query, ER_SAFE(expected_error), expected_error, actual_error ? thd->net.last_error: "no error", actual_error, - print_slave_db_safe((char*)db)); + print_slave_db_safe(db)); thd->query_error= 1; } /* @@ -1837,11 +1839,12 @@ got on master - got on master: '%s' (%d), got on slave: '%s' (%d) \ */ else if (thd->query_error || thd->fatal_error) { - slave_print_error(rli,actual_error, "Error '%s' on query '%s' \ -(default database was '%s')", - actual_error ? thd->net.last_error : - "unexpected success or fatal error", query, - print_slave_db_safe((char*)db)); + slave_print_error(rli,actual_error, + "Error '%s' on query '%s'. Default database: '%s'", + (actual_error ? thd->net.last_error : + "unexpected success or fatal error"), + query, + print_slave_db_safe(db)); thd->query_error= 1; } } @@ -1896,7 +1899,7 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, bool use_rli_only_for_errors) { init_sql_alloc(&thd->mem_root, 8192,0); - thd->db = rewrite_db((char*)db); + thd->db= (char*) rewrite_db(db); DBUG_ASSERT(thd->query == 0); thd->query = 0; // Should not be needed thd->query_error = 0; @@ -1978,17 +1981,15 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, if (mysql_load(thd, &ex, &tables, field_list, handle_dup, net != 0, TL_WRITE)) thd->query_error = 1; + /* log_pos is the position of the LOAD event in the master log */ if (thd->cuted_fields) - /* - log_pos is the position of the LOAD - event in the master log - */ - sql_print_error("Slave: load data infile at position %s in log \ -'%s' produced %d warning(s) (loaded table was '%s', database was '%s')", + sql_print_error("\ +Slave: load data infile on table '%s' at log position %s in log \ +'%s' produced %ld warning(s). Default database: '%s'", + (char*) table_name, llstr(log_pos,llbuff), RPL_LOG_NAME, - thd->cuted_fields, - (char*)table_name, - print_slave_db_safe((char*)db)); + (ulong) thd->cuted_fields, + print_slave_db_safe(db)); if (net) net->pkt_nr= thd->net.pkt_nr; } @@ -2019,10 +2020,9 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, sql_errno=ER_UNKNOWN_ERROR; err=ER(sql_errno); } - slave_print_error(rli,sql_errno, - "Error '%s' running load data infile \ -(loaded table was '%s', database was '%s')", - err, (char*)table_name, print_slave_db_safe((char*)db)); + slave_print_error(rli,sql_errno,"\ +Error '%s' running lOAD DATA INFILE on table '%s'. Default database: '%s'", + err, (char*)table_name, print_slave_db_safe(db)); free_root(&thd->mem_root,0); return 1; } @@ -2030,10 +2030,9 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, if (thd->fatal_error) { - slave_print_error(rli,ER_UNKNOWN_ERROR, -"Fatal error running \ -LOAD DATA INFILE (loaded table was '%s', database was '%s')", - (char*)table_name, print_slave_db_safe((char*)db)); + slave_print_error(rli,ER_UNKNOWN_ERROR, "\ +Fatal error running LOAD DATA INFILE on table '%s'. Default database: '%s'", + (char*)table_name, print_slave_db_safe(db)); return 1; } @@ -2339,13 +2338,15 @@ int Execute_load_log_event::exec_event(struct st_relay_log_info* rli) What we want instead is add the filename to the current error message. */ char *tmp= my_strdup(rli->last_slave_error,MYF(MY_WME)); - if (!tmp) - goto err; - slave_print_error(rli,rli->last_slave_errno, /* ok to re-use the error code */ - "%s. Failed executing load from '%s'", - tmp, fname); - my_free(tmp,MYF(0)); - thd->options = save_options; + if (tmp) + { + slave_print_error(rli, + rli->last_slave_errno, /* ok to re-use error code */ + "%s. Failed executing load from '%s'", + tmp, fname); + my_free(tmp,MYF(0)); + } + thd->options= save_options; goto err; } thd->options = save_options; diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 1b625a81b0c..a8a0c639abd 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -30,8 +30,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 41807285acc..d9ba97ad11a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2506,6 +2506,19 @@ int mysql_service(void *p) return 0; } + +/* Quote string if it contains space, else copy */ + +static char *add_quoted_string(char *to, const char *from, char *to_end) +{ + uint length= (uint) (to_end-to); + + if (!strchr(from, ' ')) + return strnmov(to, from, length); + return strxnmov(to, length, "\"", from, "\"", NullS); +} + + /* Handle basic handling of services, like installation and removal @@ -2515,25 +2528,41 @@ int mysql_service(void *p) servicename Internal name of service displayname Display name of service (in taskbar ?) file_path Path to this program + startup_option Startup option to mysqld RETURN VALUES 0 option handled 1 Could not handle option */ -bool default_service_handling(char **argv, - const char *servicename, - const char *displayname, - const char *file_path) +static bool +default_service_handling(char **argv, + const char *servicename, + const char *displayname, + const char *file_path, + const char *extra_opt) { + char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end; + end= path_and_service + sizeof(path_and_service)-1; + + /* We have to quote filename if it contains spaces */ + pos= add_quoted_string(path_and_service, file_path, end); + if (*extra_opt) + { + /* Add (possible quoted) option after file_path */ + *pos++= ' '; + pos= add_quoted_string(pos, extra_opt, end); + } + *pos= 0; // Ensure end null + if (Service.got_service_option(argv, "install")) { - Service.Install(1, servicename, displayname, file_path); + Service.Install(1, servicename, displayname, path_and_service); return 0; } if (Service.got_service_option(argv, "install-manual")) { - Service.Install(0, servicename, displayname, file_path); + Service.Install(0, servicename, displayname, path_and_service); return 0; } if (Service.got_service_option(argv, "remove")) @@ -2560,12 +2589,11 @@ int main(int argc, char **argv) char file_path[FN_REFLEN]; my_path(file_path, argv[0], ""); /* Find name in path */ fn_format(file_path,argv[0],file_path,"",MY_REPLACE_DIR+ - MY_UNPACK_FILENAME+MY_RESOLVE_SYMLINKS+MY_QUOTE_SPACES); - + MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS); if (argc == 2) { - if (!default_service_handling(argv,MYSQL_SERVICENAME, MYSQL_SERVICENAME, - file_path)) + if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME, + file_path, "")) return 0; if (Service.IsService(argv[1])) { @@ -2578,12 +2606,8 @@ int main(int argc, char **argv) } else if (argc == 3) /* install or remove any optional service */ { - /* Add service name after filename */ - uint length=strlen(file_path); - *strxnmov(file_path + length, sizeof(file_path)-length-2, " ", - argv[2], NullS)= '\0'; - - if (!default_service_handling(argv, argv[2], argv[2], file_path)) + if (!default_service_handling(argv, argv[2], argv[2], file_path, + argv[2])) return 0; if (Service.IsService(argv[2])) { @@ -2605,12 +2629,8 @@ int main(int argc, char **argv) Install an optional service with optional config file mysqld --install-manual mysqldopt --defaults-file=c:\miguel\my.ini */ - uint length=strlen(file_path); - char tmp_path[FN_REFLEN]; - fn_format(tmp_path,argv[3],tmp_path,"",MY_QUOTE_SPACES); - *strxnmov(file_path + length, sizeof(file_path)-length-2, " ", - tmp_path, " ", argv[2], NullS)= '\0'; - if (!default_service_handling(argv, argv[2], argv[2], file_path)) + if (!default_service_handling(argv, argv[2], argv[2], file_path, + argv[3])) return 0; } else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME)) diff --git a/sql/slave.cc b/sql/slave.cc index b4fa11f456e..d7c8c6d5fd3 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -828,6 +828,7 @@ static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli) return rli->abort_slave || abort_loop || thd->killed; } + /* Writes an error message to rli->last_slave_error and rli->last_slave_errno (which will be displayed by SHOW SLAVE STATUS), and prints it to stderr. @@ -842,7 +843,7 @@ static bool sql_slave_killed(THD* thd, RELAY_LOG_INFO* rli) RETURN VALUES void - */ +*/ void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...) { @@ -853,11 +854,11 @@ void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...) rli->last_slave_errno = err_code; /* If the error string ends with '.', do not add a ',' it would be ugly */ if (rli->last_slave_error[0] && - (rli->last_slave_error[strlen(rli->last_slave_error)-1] == '.')) - sql_print_error("Slave: %s Error_code=%d", rli->last_slave_error, + (*(strend(rli->last_slave_error)-1) == '.')) + sql_print_error("Slave: %s Error_code: %d", rli->last_slave_error, err_code); else - sql_print_error("Slave: %s, error_code=%d", rli->last_slave_error, + sql_print_error("Slave: %s, Error_code: %d", rli->last_slave_error, err_code); } @@ -872,7 +873,7 @@ void skip_load_data_infile(NET* net) } -char* rewrite_db(char* db) +const char *rewrite_db(const char* db) { if (replicate_rewrite_db.is_empty() || !db) return db; @@ -889,13 +890,14 @@ char* rewrite_db(char* db) /* From other comments and tests in code, it looks like - sometimes Query_log_event and Load_log_event can have db==0 + sometimes Query_log_event and Load_log_event can have db == 0 (see rewrite_db() above for example) (cases where this happens are unclear; it may be when the master is 3.23). */ -char* print_slave_db_safe(char* db) + +const char *print_slave_db_safe(const char* db) { - return (db ? rewrite_db(db) : (char*) ""); + return (db ? rewrite_db(db) : ""); } /* @@ -1303,8 +1305,8 @@ file '%s', errno %d)", fname, my_errno); if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L,0, MYF(MY_WME))) { - sql_print_error("Failed to create a cache on relay log info file (\ -file '%s')", fname); + sql_print_error("Failed to create a cache on relay log info file '%s'", + fname); msg= current_thd->net.last_error; goto err; } @@ -1313,8 +1315,7 @@ file '%s')", fname); if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */, &msg)) { - sql_print_error("Failed to open the relay log (relay_log_name='FIRST', \ -relay_log_pos=4)"); + sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4"); goto err; } rli->master_log_name[0]= 0; @@ -1330,15 +1331,16 @@ relay_log_pos=4)"); int error=0; if ((info_fd = my_open(fname, O_RDWR|O_BINARY, MYF(MY_WME))) < 0) { - sql_print_error("Failed to open the existing relay log info file (\ -file '%s', errno %d)", fname, my_errno); + sql_print_error("\ +Failed to open the existing relay log info file '%s' (errno %d)", + fname, my_errno); error= 1; } else if (init_io_cache(&rli->info_file, info_fd, IO_SIZE*2, READ_CACHE, 0L, 0, MYF(MY_WME))) { - sql_print_error("Failed to create a cache on relay log info file (\ -file '%s')", fname); + sql_print_error("Failed to create a cache on relay log info file '%s'", + fname); error= 1; } if (error) @@ -1377,8 +1379,8 @@ file '%s')", fname); &msg)) { char llbuf[22]; - sql_print_error("Failed to open the relay log (relay_log_name='%s', \ -relay_log_pos=%s)", rli->relay_log_name, llstr(rli->relay_log_pos, llbuf)); + sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s)", + rli->relay_log_name, llstr(rli->relay_log_pos, llbuf)); goto err; } } diff --git a/sql/slave.h b/sql/slave.h index d1fd54d3c04..42776061545 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -382,8 +382,8 @@ int add_table_rule(HASH* h, const char* table_spec); int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec); void init_table_rule_hash(HASH* h, bool* h_inited); void init_table_rule_array(DYNAMIC_ARRAY* a, bool* a_inited); -char* rewrite_db(char* db); -char* print_slave_db_safe(char* db); +const char *rewrite_db(const char* db); +const char *print_slave_db_safe(const char* db); int check_expected_error(THD* thd, RELAY_LOG_INFO* rli, int error_code); void skip_load_data_infile(NET* net); void slave_print_error(RELAY_LOG_INFO* rli, int err_code, const char* msg, ...); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 3a3de2abf10..877eab74110 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1242,13 +1242,12 @@ static bool update_user_table(THD *thd, const char *host, const char *user, { /* The tables must be marked "updating" so that tables_ok() takes them into - account in tests. + account in tests. It's ok to leave 'updating' set after tables_ok. */ - tables.updating=1; + tables.updating= 1; /* Thanks to bzero, tables.next==0 */ if (!tables_ok(0, &tables)) DBUG_RETURN(0); - tables.updating=0; } #endif @@ -2138,10 +2137,9 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, The tables must be marked "updating" so that tables_ok() takes them into account in tests. */ - tables[0].updating=tables[1].updating=tables[2].updating=1; + tables[0].updating= tables[1].updating= tables[2].updating= 1; if (!tables_ok(0, tables)) DBUG_RETURN(0); - tables[0].updating=tables[1].updating=tables[2].updating=0; } #endif @@ -2319,10 +2317,9 @@ int mysql_grant (THD *thd, const char *db, List &list, The tables must be marked "updating" so that tables_ok() takes them into account in tests. */ - tables[0].updating=tables[1].updating=1; + tables[0].updating= tables[1].updating= 1; if (!tables_ok(0, tables)) DBUG_RETURN(0); - tables[0].updating=tables[1].updating=0; } #endif diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 72ac915d14e..69d4f3007b8 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -18,8 +18,8 @@ #ifdef HAVE_OPENSSL -#include #include +#include #include From d78830457b351419172691bc93ca7cd08586cf67 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Thu, 7 Aug 2003 20:42:26 +0300 Subject: [PATCH 231/237] Fix that -integer works as in 4.0 --- acinclude.m4 | 15 ++++++++--- sql/item_func.cc | 70 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index 94e70f2b892..2b91d52d749 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -746,7 +746,7 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ /usr/include/ssl /opt/ssl/include /opt/openssl/include \ /usr/local/ssl/include /usr/local/include ; do if test -f $d/openssl/ssl.h ; then - OPENSSL_INCLUDE=$d + OPENSSL_INCLUDE=-I$d fi done @@ -757,6 +757,15 @@ AC_DEFUN(MYSQL_FIND_OPENSSL, [ fi done + # On RedHat 9 we need kerberos to compile openssl + for d in /usr/kerberos/include + do + if test -f $d/krb5.h ; then + OPENSSL_INCLUDE="$OPENSSL_INCLUDE -I$d" + fi + done + + if test -z "$OPENSSL_LIB" -o -z "$OPENSSL_INCLUDE" ; then echo "Could not find an installation of OpenSSL" if test -n "$OPENSSL_LIB" ; then @@ -789,9 +798,9 @@ AC_MSG_CHECKING(for OpenSSL) openssl_libs="-L$OPENSSL_LIB -lssl -lcrypto" # Don't set openssl_includes to /usr/include as this gives us a lot of # compiler warnings when using gcc 3.x - if test "$OPENSSL_INCLUDE" != "/usr/include" + if test "$OPENSSL_INCLUDE" != "-I/usr/include" then - openssl_includes="-I$OPENSSL_INCLUDE" + openssl_includes="$OPENSSL_INCLUDE" fi AC_DEFINE(HAVE_OPENSSL) diff --git a/sql/item_func.cc b/sql/item_func.cc index 9ecc062d645..e2e60c43f58 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -22,7 +22,7 @@ #endif #include "mysql_priv.h" -#include "slave.h" // for wait_for_master_pos +#include "slave.h" // for wait_for_master_pos #include #include #include @@ -31,7 +31,9 @@ #include #endif -static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) + +static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, + const char *fname) { my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), c1.collation->name,c1.derivation_name(), @@ -39,6 +41,7 @@ static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fnam fname); } + static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, DTCollation &c3, @@ -51,11 +54,12 @@ static void my_coll_agg_error(DTCollation &c1, fname); } -static void my_coll_agg_error(Item** args, uint ac, const char *fname) + +static void my_coll_agg_error(Item** args, uint count, const char *fname) { - if (2 == ac) + if (count == 2) my_coll_agg_error(args[0]->collation, args[1]->collation, fname); - else if (3 == ac) + else if (count == 3) my_coll_agg_error(args[0]->collation, args[1]->collation, args[2]->collation, @@ -64,30 +68,32 @@ static void my_coll_agg_error(Item** args, uint ac, const char *fname) my_error(ER_CANT_AGGREGATE_NCOLLATIONS,MYF(0),fname); } -bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint ac) + +bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count) { uint i; c.set(av[0]->collation); - for (i= 1; i < ac; i++) + for (i= 1; i < count; i++) { if (c.aggregate(av[i]->collation)) { - my_coll_agg_error(av, ac, func_name()); + my_coll_agg_error(av, count, func_name()); return TRUE; } } return FALSE; } + bool Item_func::agg_arg_collations_for_comparison(DTCollation &c, - Item **av, uint ac) + Item **av, uint count) { - if (agg_arg_collations(c, av, ac)) + if (agg_arg_collations(c, av, count)) return TRUE; if (c.derivation == DERIVATION_NONE) { - my_coll_agg_error(av, ac, func_name()); + my_coll_agg_error(av, count, func_name()); return TRUE; } return FALSE; @@ -102,6 +108,7 @@ eval_const_cond(COND *cond) return ((Item_func*) cond)->val_int() ? TRUE : FALSE; } + void Item_func::set_arguments(List &list) { allowed_arg_cols= 1; @@ -586,6 +593,7 @@ double Item_func_neg::val() return -value; } + longlong Item_func_neg::val_int() { longlong value=args[0]->val_int(); @@ -593,14 +601,32 @@ longlong Item_func_neg::val_int() return -value; } + void Item_func_neg::fix_length_and_dec() { decimals=args[0]->decimals; max_length=args[0]->max_length; - hybrid_type= args[0]->result_type() == INT_RESULT && !args[0]->unsigned_flag ? - INT_RESULT : REAL_RESULT; + hybrid_type= REAL_RESULT; + if (args[0]->result_type() == INT_RESULT) + { + /* + If this is in integer context keep the context as integer + (This is how multiplication and other integer functions works) + + We must however do a special case in the case where the argument + is a unsigned bigint constant as in this case the only safe + number to convert in integer context is 9223372036854775808. + (This is needed because the lex parser doesn't anymore handle + signed integers) + */ + if (args[0]->type() != INT_ITEM || + ((ulonglong) ((Item_uint*) args[0])->value <= + (ulonglong) LONGLONG_MIN)) + hybrid_type= INT_RESULT; + } } + double Item_func_abs::val() { double value=args[0]->val(); @@ -608,6 +634,7 @@ double Item_func_abs::val() return fabs(value); } + longlong Item_func_abs::val_int() { longlong value=args[0]->val_int(); @@ -615,13 +642,20 @@ longlong Item_func_abs::val_int() return value >= 0 ? value : -value; } + void Item_func_abs::fix_length_and_dec() { decimals=args[0]->decimals; max_length=args[0]->max_length; - hybrid_type= args[0]->result_type() == INT_RESULT ? INT_RESULT : REAL_RESULT; + hybrid_type= REAL_RESULT; + if (args[0]->result_type() == INT_RESULT) + { + hybrid_type= INT_RESULT; + unsigned_flag= 1; + } } + /* Gateway to natural LOG function */ double Item_func_ln::val() { @@ -1051,6 +1085,7 @@ longlong Item_func_crc32::val_int() return (longlong) crc32(0L, (Bytef*)res->ptr(), res->length()); } + longlong Item_func_uncompressed_length::val_int() { String *res= args[0]->val_str(&value); @@ -1063,9 +1098,9 @@ longlong Item_func_uncompressed_length::val_int() if (res->is_empty()) return 0; return uint4korr(res->c_ptr()) & 0x3FFFFFFF; } - #endif /* HAVE_COMPRESS */ + longlong Item_func_length::val_int() { String *res=args[0]->val_str(&value); @@ -1078,6 +1113,7 @@ longlong Item_func_length::val_int() return (longlong) res->length(); } + longlong Item_func_char_length::val_int() { String *res=args[0]->val_str(&value); @@ -1090,6 +1126,7 @@ longlong Item_func_char_length::val_int() return (longlong) res->numchars(); } + longlong Item_func_coercibility::val_int() { if (args[0]->null_value) @@ -1101,12 +1138,14 @@ longlong Item_func_coercibility::val_int() return (longlong) args[0]->derivation(); } + void Item_func_locate::fix_length_and_dec() { maybe_null=0; max_length=11; agg_arg_collations_for_comparison(cmp_collation, args, 2); } + longlong Item_func_locate::val_int() { String *a=args[0]->val_str(&value1); @@ -1207,6 +1246,7 @@ longlong Item_func_field::val_int() return 0; } + void Item_func_field::fix_length_and_dec() { maybe_null=0; max_length=3; From 2964e4ab48cfdebc34280a001f9b52236dfa4780 Mon Sep 17 00:00:00 2001 From: "kostja@oak.local" <> Date: Thu, 14 Aug 2003 13:19:17 +0400 Subject: [PATCH 232/237] added compile-pentium-maintainer - equivalent of compile-pentium-debug but with --enable-maintainer-mode configure option Maybe it's worth to merge compile-mentium-debug and compile-pentium-maintainer to a single script --- BUILD/compile-pentium-maintainer | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100755 BUILD/compile-pentium-maintainer diff --git a/BUILD/compile-pentium-maintainer b/BUILD/compile-pentium-maintainer new file mode 100755 index 00000000000..1265154dc76 --- /dev/null +++ b/BUILD/compile-pentium-maintainer @@ -0,0 +1,13 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +extra_flags="$pentium_cflags $debug_cflags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$pentium_configs $debug_configs " + +extra_configs="$extra_configs --enable-maintainer-mode" + +. "$path/FINISH.sh" From 762ca8b6f888d0b94f993369dcdba2532d9eae88 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Mon, 18 Aug 2003 17:24:50 +0500 Subject: [PATCH 233/237] Fix strnxfrm_multiplye from 0 to 1 for charsets that do not use strnxfrm --- strings/ctype-big5.c | 2 +- strings/ctype-bin.c | 2 +- strings/ctype-euc_kr.c | 4 ++-- strings/ctype-gb2312.c | 4 ++-- strings/ctype-gbk.c | 2 +- strings/ctype-latin1.c | 4 ++-- strings/ctype-sjis.c | 2 +- strings/ctype-tis620.c | 2 +- strings/ctype-ucs2.c | 2 +- strings/ctype-ujis.c | 4 ++-- strings/ctype-utf8.c | 2 +- 11 files changed, 15 insertions(+), 15 deletions(-) diff --git a/strings/ctype-big5.c b/strings/ctype-big5.c index 10b6898ce24..88309aadaa0 100644 --- a/strings/ctype-big5.c +++ b/strings/ctype-big5.c @@ -6300,7 +6300,7 @@ CHARSET_INFO my_charset_big5_bin= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, &my_charset_big5_handler, diff --git a/strings/ctype-bin.c b/strings/ctype-bin.c index ebe73016db7..10ea23e07eb 100644 --- a/strings/ctype-bin.c +++ b/strings/ctype-bin.c @@ -312,7 +312,7 @@ CHARSET_INFO my_charset_bin = NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ "","", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 1, /* mbmaxlen */ (char) 255, /* max_sort_char */ &my_charset_handler, diff --git a/strings/ctype-euc_kr.c b/strings/ctype-euc_kr.c index 8e288ee8e55..e8d2c8c4d1d 100644 --- a/strings/ctype-euc_kr.c +++ b/strings/ctype-euc_kr.c @@ -8686,7 +8686,7 @@ CHARSET_INFO my_charset_euckr_korean_ci= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, &my_charset_handler, @@ -8709,7 +8709,7 @@ CHARSET_INFO my_charset_euckr_bin= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-gb2312.c b/strings/ctype-gb2312.c index 378931eecc7..72548305ad1 100644 --- a/strings/ctype-gb2312.c +++ b/strings/ctype-gb2312.c @@ -5736,7 +5736,7 @@ CHARSET_INFO my_charset_gb2312_chinese_ci= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, &my_charset_handler, @@ -5758,7 +5758,7 @@ CHARSET_INFO my_charset_gb2312_bin= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-gbk.c b/strings/ctype-gbk.c index 58d281ae485..84819d2e1a8 100644 --- a/strings/ctype-gbk.c +++ b/strings/ctype-gbk.c @@ -9955,7 +9955,7 @@ CHARSET_INFO my_charset_gbk_bin= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index b0c60e2e3eb..24e06df19a1 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -213,7 +213,7 @@ CHARSET_INFO my_charset_latin1= latin1_uni, /* tab_to_uni */ NULL, /* tab_from_uni */ "","", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 1, /* mbmaxlen */ 0, &my_charset_handler, @@ -477,7 +477,7 @@ CHARSET_INFO my_charset_latin1_bin= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 1, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-sjis.c b/strings/ctype-sjis.c index 00d51dd23b5..d8443165462 100644 --- a/strings/ctype-sjis.c +++ b/strings/ctype-sjis.c @@ -4542,7 +4542,7 @@ CHARSET_INFO my_charset_sjis_bin= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-tis620.c b/strings/ctype-tis620.c index ab51ddd013f..643ea77c73e 100644 --- a/strings/ctype-tis620.c +++ b/strings/ctype-tis620.c @@ -762,7 +762,7 @@ CHARSET_INFO my_charset_tis620_bin= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 1, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-ucs2.c b/strings/ctype-ucs2.c index 5d78ab5dcff..6c0cfd3e874 100644 --- a/strings/ctype-ucs2.c +++ b/strings/ctype-ucs2.c @@ -1077,7 +1077,7 @@ CHARSET_INFO my_charset_ucs2_bin= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 2, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-ujis.c b/strings/ctype-ujis.c index eb31c49013a..c6cf6ff79ba 100644 --- a/strings/ctype-ujis.c +++ b/strings/ctype-ujis.c @@ -8477,7 +8477,7 @@ CHARSET_INFO my_charset_ujis_japanese_ci= NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ "","", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 3, /* mbmaxlen */ 0, &my_charset_handler, @@ -8499,7 +8499,7 @@ CHARSET_INFO my_charset_ujis_bin= NULL, /* tab_to_uni */ NULL, /* tab_from_uni */ "","", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 3, /* mbmaxlen */ 0, &my_charset_handler, diff --git a/strings/ctype-utf8.c b/strings/ctype-utf8.c index 1982b9e3ba8..4ac397c4c48 100644 --- a/strings/ctype-utf8.c +++ b/strings/ctype-utf8.c @@ -2026,7 +2026,7 @@ CHARSET_INFO my_charset_utf8_bin= NULL, /* tab_from_uni */ "", "", - 0, /* strxfrm_multiply */ + 1, /* strxfrm_multiply */ 3, /* mbmaxlen */ 0, &my_charset_handler, From 9b5deb8fe1d474efa31b3f79280d4cece5de7027 Mon Sep 17 00:00:00 2001 From: "bar@bar.mysql.r18.ru" <> Date: Mon, 18 Aug 2003 17:27:09 +0500 Subject: [PATCH 234/237] Adding Gerogian GEOSTD8 character set --- sql/share/charsets/Index.xml | 9 ++- sql/share/charsets/geostd8.xml | 121 +++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 sql/share/charsets/geostd8.xml diff --git a/sql/share/charsets/Index.xml b/sql/share/charsets/Index.xml index c5a2ae5dfb6..3661784325c 100644 --- a/sql/share/charsets/Index.xml +++ b/sql/share/charsets/Index.xml @@ -1,6 +1,6 @@ - + This file lists all of the available character sets. @@ -522,6 +522,13 @@ To make maintaining easier please: + + South Asian + GEOSTD8 Georgian + + + + Binary pseudo charset diff --git a/sql/share/charsets/geostd8.xml b/sql/share/charsets/geostd8.xml new file mode 100644 index 00000000000..caf01af58d0 --- /dev/null +++ b/sql/share/charsets/geostd8.xml @@ -0,0 +1,121 @@ + + + + + + + + + 00 + 20 20 20 20 20 20 20 20 20 28 28 28 28 28 20 20 + 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 + 48 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 + 84 84 84 84 84 84 84 84 84 84 10 10 10 10 10 10 + 10 81 81 81 81 81 81 01 01 01 01 01 01 01 01 01 + 01 01 01 01 01 01 01 01 01 01 01 10 10 10 10 10 + 10 82 82 82 82 82 82 02 02 02 02 02 02 02 02 02 + 02 02 02 02 02 02 02 02 02 02 02 10 10 10 10 20 + 00 00 10 00 10 10 10 10 00 10 00 10 00 00 00 00 + 00 10 10 10 10 10 10 10 00 00 00 10 00 00 00 00 + 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 + 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03 + 03 03 03 03 03 03 00 00 00 00 00 00 00 00 00 00 + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 + + + + + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 5B 5C 5D 5E 5F + 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F + 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + + + + + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 60 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + + + + + + +0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F +0010 0011 0012 0013 0014 0015 0016 0017 0018 0019 001A 001B 001C 001D 001E 001F +0020 0021 0022 0023 0024 0025 0026 0027 0028 0029 002A 002B 002C 002D 002E 002F +0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 003A 003B 003C 003D 003E 003F +0040 0041 0042 0043 0044 0045 0046 0047 0048 0049 004A 004B 004C 004D 004E 004F +0050 0051 0052 0053 0054 0055 0056 0057 0058 0059 005A 005B 005C 005D 005E 005F +0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 006A 006B 006C 006D 006E 006F +0070 0071 0072 0073 0074 0075 0076 0077 0078 0079 007A 007B 007C 007D 007E 007F +20AC 0000 201A 0000 201E 2026 2020 2021 0000 2030 0000 2039 0000 0000 0000 0000 +0000 2018 2019 201C 201D 2022 2013 2014 0000 0000 0000 203A 0000 0000 0000 0000 +00A0 00A1 00A2 00A3 00A4 00A5 00A6 00A7 00A8 00A9 00AA 00AB 00AC 00AD 00AE 00AF +00B0 00B1 00B2 00B3 00B4 00B5 00B6 00B7 00B8 00B9 00BA 00BB 00BC 00BD 00BE 00BF +10D0 10D1 10D2 10D3 10D4 10D5 10D6 10F1 10D7 10D8 10D9 10DA 10DB 10DC 10F2 10DD +10DE 10DF 10E0 10E1 10E2 10F3 10E3 10E4 10E5 10E6 10E7 10E8 10E9 10EA 10EB 10EC +10ED 10EE 10F4 10EF 10F0 10F5 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 +0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 2116 0000 0000 + + + + + + + 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F + 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F + 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F + 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F + 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F + 50 51 52 53 54 55 56 57 58 59 5A 7B 7C 7D 7E 7F + 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F + 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F + A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF + B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF + C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF + E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF + + + + + + + + From 4f7512160bfd467e5d53c3e133e1842fac2737ce Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Tue, 19 Aug 2003 00:08:08 +0300 Subject: [PATCH 235/237] After merge fixes Use server character set if --default-character-set is not used Added convert_string() for more efficient alloc+character-set convert of strings --- client/mysql.cc | 9 +- client/mysqltest.c | 31 +- heap/hp_create.c | 1 + include/m_ctype.h | 2 +- include/my_global.h | 3 - include/mysql_com.h | 4 +- libmysql/libmysql.c | 3 +- libmysqld/Makefile.am | 3 +- mysql-test/r/auto_increment.result | 7 +- mysql-test/r/convert.result | 17 - mysql-test/r/create.result | 6 +- mysql-test/r/ctype_latin1_de.result | 3 + mysql-test/r/distinct.result | 4 +- mysql-test/r/drop.result | 6 +- mysql-test/r/fulltext.result | 46 ++ mysql-test/r/func_gconcat.result | 4 +- mysql-test/r/func_str.result | 6 +- mysql-test/r/func_test.result | 28 +- mysql-test/r/grant.result | 40 +- mysql-test/r/group_by.result | 60 +-- mysql-test/r/handler.result | 23 +- mysql-test/r/heap.result | 12 +- mysql-test/r/heap_btree.result | 8 +- mysql-test/r/heap_hash.result | 10 +- mysql-test/r/innodb.result | 61 +-- mysql-test/r/insert.result | 4 +- mysql-test/r/insert_select.result | 7 +- mysql-test/r/join_outer.result | 2 +- mysql-test/r/key.result | 17 +- mysql-test/r/key_cache.result | 2 +- mysql-test/r/loaddata.result | 20 +- mysql-test/r/myisam.result | 37 +- mysql-test/r/null.result | 20 +- mysql-test/r/null_key.result | 4 +- mysql-test/r/order_by.result | 14 +- mysql-test/r/rpl_do_grant.result | 4 +- mysql-test/r/rpl_error_ignored_table.result | 10 +- mysql-test/r/rpl_ignore_grant.result | 6 +- mysql-test/r/rpl_loaddata.result | 12 +- mysql-test/r/rpl_log.result | 2 +- mysql-test/r/rpl_log_pos.result | 4 +- mysql-test/r/rpl_max_relay_size.result | 30 +- mysql-test/r/rpl_replicate_do.result | 2 +- mysql-test/r/rpl_reset_slave.result | 20 +- mysql-test/r/rpl_rotate_logs.result | 4 +- mysql-test/r/rpl_user_variables.result | 12 +- mysql-test/r/select.result | 62 +-- mysql-test/r/select_safe.result | 14 +- mysql-test/r/subselect.result | 29 +- mysql-test/r/type_blob.result | 6 +- mysql-test/r/type_decimal.result | 109 ++--- mysql-test/r/type_float.result | 4 +- mysql-test/r/type_ranges.result | 66 +-- mysql-test/r/type_time.result | 6 +- mysql-test/r/type_uint.result | 3 +- mysql-test/r/union.result | 9 +- mysql-test/r/warnings.result | 91 ++-- mysql-test/t/auto_increment.test | 1 + mysql-test/t/case.test | 8 +- mysql-test/t/convert.test | 11 - mysql-test/t/ctype_collate.test | 15 +- mysql-test/t/ctype_latin1_de.test | 4 + mysql-test/t/drop.test | 2 +- mysql-test/t/func_in.test | 6 +- mysql-test/t/func_set.test | 2 +- mysql-test/t/func_str.test | 46 +- mysql-test/t/func_test.test | 30 +- mysql-test/t/grant.test | 16 +- mysql-test/t/group_by.test | 2 +- mysql-test/t/handler.test | 6 +- mysql-test/t/heap.test | 2 +- mysql-test/t/heap_btree.test | 2 +- mysql-test/t/heap_hash.test | 2 +- mysql-test/t/innodb.test | 2 +- mysql-test/t/insert_select.test | 1 - mysql-test/t/key.test | 9 +- mysql-test/t/key_cache.test | 2 +- .../t/lock_tables_lost_commit-master.opt | 2 +- mysql-test/t/lock_tables_lost_commit.test | 2 + mysql-test/t/myisam.test | 3 + mysql-test/t/row.test | 14 +- mysql-test/t/subselect.test | 51 ++- mysql-test/t/type_decimal.test | 1 + mysql-test/t/type_ranges.test | 1 + mysql-test/t/type_uint.test | 1 + mysql-test/t/variables.test | 2 +- mysql-test/t/warnings.test | 1 + scripts/make_win_src_distribution.old | 402 ------------------ scripts/make_win_src_distribution.sh | 2 +- sql-common/client.c | 121 ++++-- sql/field.cc | 30 +- sql/ha_myisammrg.h | 3 +- sql/log.cc | 3 - sql/log_event.cc | 14 +- sql/mysqld.cc | 8 +- sql/opt_range.cc | 2 +- sql/set_var.cc | 120 ++++-- sql/set_var.h | 38 +- sql/slave.cc | 8 +- sql/sql_acl.cc | 16 +- sql/sql_class.cc | 53 +++ sql/sql_class.h | 5 + sql/sql_handler.cc | 2 +- sql/sql_lex.h | 2 + sql/sql_parse.cc | 65 +-- sql/sql_repl.cc | 8 +- sql/sql_yacc.yy | 96 ++--- strings/ctype-latin1.c | 281 +++++------- 108 files changed, 1126 insertions(+), 1429 deletions(-) delete mode 100644 mysql-test/r/convert.result delete mode 100644 mysql-test/t/convert.test delete mode 100755 scripts/make_win_src_distribution.old diff --git a/client/mysql.cc b/client/mysql.cc index 0b6485172e4..b249ccbfbc5 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -133,7 +133,8 @@ static my_bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, opt_compress=0, using_opt_local_infile=0, vertical=0, line_numbers=1, column_names=1,opt_html=0, opt_xml=0,opt_nopager=1, opt_outfile=0, named_cmds= 0, - tty_password= 0, opt_nobeep=0, opt_reconnect=1; + tty_password= 0, opt_nobeep=0, opt_reconnect=1, + default_charset_used= 0; static uint verbose=0,opt_silent=0,opt_mysql_port=0, opt_local_infile=0; static my_string opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; @@ -651,6 +652,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), strmov(mysql_charsets_dir, argument); charsets_dir = mysql_charsets_dir; break; + case OPT_DEFAULT_CHARSET: + default_charset_used= 1; + break; case OPT_DELIMITER: if (argument == disabled_my_option) strmov(delimiter, DEFAULT_DELIMITER); @@ -2563,7 +2567,8 @@ sql_real_connect(char *host,char *database,char *user,char *password, select_limit,max_join_size); mysql_options(&mysql, MYSQL_INIT_COMMAND, init_command); } - mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); + if (default_charset_used) + mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset); if (!mysql_real_connect(&mysql, host, user, password, database, opt_mysql_port, opt_mysql_unix_port, connect_flag | CLIENT_MULTI_QUERIES)) diff --git a/client/mysqltest.c b/client/mysqltest.c index a3b5facae9c..3b814b27810 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -722,8 +722,8 @@ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) int done; LINT_INIT(res); - if (mysql_query(mysql,"show status like 'Slave_running'") - || !(res=mysql_store_result(mysql))) + if (mysql_query(mysql,"show status like 'Slave_running'") || + !(res=mysql_store_result(mysql))) die("Query failed while probing slave for stop: %s", mysql_error(mysql)); if (!(row=mysql_fetch_row(res)) || !row[1]) @@ -2183,19 +2183,21 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) goto end; /* Ok */ } } - if (i) - { - replace_dynstr_append_mem(ds, mysql_error(mysql), - strlen(mysql_error(mysql))); - dynstr_append_mem(ds,"\n",1); - verbose_msg("query '%s' failed with wrong errno %d instead of %d...", - q->query, mysql_errno(mysql), q->expected_errno[0]); - error=1; - goto end; - } - replace_dynstr_append_mem(ds,mysql_error(mysql), + DBUG_PRINT("info",("i: %d expected_errors: %d", i, q->expected_errors)); + dynstr_append_mem(ds,"ERROR ",6); + replace_dynstr_append_mem(ds, mysql_sqlstate(mysql), + strlen(mysql_sqlstate(mysql))); + dynstr_append_mem(ds,": ",2); + replace_dynstr_append_mem(ds, mysql_error(mysql), strlen(mysql_error(mysql))); dynstr_append_mem(ds,"\n",1); + if (i) + { + verbose_msg("query '%s' failed with wrong errno %d instead of %d...", + q->query, mysql_errno(mysql), q->expected_errno[0]); + error= 1; + goto end; + } verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql), mysql_error(mysql)); /* @@ -2608,7 +2610,8 @@ int main(int argc, char **argv) } dynstr_free(&ds_res); - if (!silent) { + if (!silent) + { if (error) printf("not ok\n"); else diff --git a/heap/hp_create.c b/heap/hp_create.c index 5265607ce53..02725576c8f 100644 --- a/heap/hp_create.c +++ b/heap/hp_create.c @@ -50,6 +50,7 @@ int heap_create(const char *name, uint keys, HP_KEYDEF *keydef, length+= keyinfo->seg[j].length; if (keyinfo->seg[j].null_bit) { + length++; if (!(keyinfo->flag & HA_NULL_ARE_EQUAL)) keyinfo->flag|= HA_NULL_PART_KEY; if (keyinfo->algorithm == HA_KEY_ALG_BTREE) diff --git a/include/m_ctype.h b/include/m_ctype.h index f6b5a1ca44f..4ae6734a48c 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -79,7 +79,7 @@ enum my_lex_states { MY_LEX_START, MY_LEX_CHAR, MY_LEX_IDENT, MY_LEX_IDENT_SEP, MY_LEX_IDENT_START, - MY_LEX_FOUND_IDENT, MY_LEX_SIGNED_NUMBER, MY_LEX_REAL, MY_LEX_HEX_NUMBER, + MY_LEX_FOUND_IDENT, MY_LEX_REAL, MY_LEX_HEX_NUMBER, MY_LEX_CMP_OP, MY_LEX_LONG_CMP_OP, MY_LEX_STRING, MY_LEX_COMMENT, MY_LEX_END, MY_LEX_OPERATOR_OR_IDENT, MY_LEX_NUMBER_IDENT, MY_LEX_INT_OR_REAL, MY_LEX_REAL_OR_POINT, MY_LEX_BOOL, MY_LEX_EOL, MY_LEX_ESCAPE, diff --git a/include/my_global.h b/include/my_global.h index 98f666548a5..0e576730ca3 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -742,9 +742,6 @@ typedef unsigned __int64 my_ulonglong; typedef unsigned long long my_ulonglong; #endif -/* typedef used for length of string; Should be unsigned! */ -typedef ulong size_str; - #ifdef USE_RAID /* The following is done with a if to not get problems with pre-processors diff --git a/include/mysql_com.h b/include/mysql_com.h index acfcd221432..b1c94e5c735 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -253,8 +253,8 @@ unsigned long my_net_read(NET *net); Currently it's used internally by manager.c */ struct sockaddr; -my_bool my_connect(my_socket s, const struct sockaddr *name, - unsigned int namelen, unsigned int timeout); +int my_connect(my_socket s, const struct sockaddr *name, unsigned int namelen, + unsigned int timeout); struct rand_struct { unsigned long seed1,seed2,max_value; diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 57613b68448..19cfedce51d 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -46,11 +46,10 @@ #ifdef HAVE_SYS_SELECT_H #include #endif -#endif +#endif /* !defined(MSDOS) && !defined(__WIN__) */ #ifdef HAVE_POLL #include #endif -#endif /* !defined(MSDOS) && !defined(__WIN__) */ #ifdef HAVE_SYS_UN_H #include #endif diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am index e61e7833451..b22ff9e5001 100644 --- a/libmysqld/Makefile.am +++ b/libmysqld/Makefile.am @@ -26,7 +26,8 @@ DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \ -DDATADIR="\"$(MYSQLDATAdir)\"" \ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" INCLUDES= @MT_INCLUDES@ @bdb_includes@ -I$(top_srcdir)/include \ - -I$(top_srcdir)/sql -I$(top_srcdir)/regex + -I$(top_srcdir)/sql -I$(top_srcdir)/regex \ + $(openssl_includes) noinst_LIBRARIES = libmysqld_int.a pkglib_LIBRARIES = libmysqld.a diff --git a/mysql-test/r/auto_increment.result b/mysql-test/r/auto_increment.result index 03cfcc50e17..8c898bae699 100644 --- a/mysql-test/r/auto_increment.result +++ b/mysql-test/r/auto_increment.result @@ -1,4 +1,5 @@ drop table if exists t1; +SET SQL_WARNINGS=1; create table t1 (a int not null auto_increment,b int, primary key (a)) type=myisam auto_increment=3; insert into t1 values (1,1),(NULL,3),(NULL,4); delete from t1 where a=4; @@ -130,7 +131,7 @@ last_insert_id() 255 insert into t1 set i = null; Warnings: -Warning 1262 Data truncated, out of range for column 'i' at row 1 +Warning 1263 Data truncated, out of range for column 'i' at row 1 select last_insert_id(); last_insert_id() 255 @@ -181,7 +182,7 @@ a b delete from t1 where a=0; update t1 set a=NULL where b=6; Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'a' at row 4 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 4 update t1 set a=300 where b=7; SET SQL_MODE=''; insert into t1(a,b)values(NULL,8); @@ -223,7 +224,7 @@ a b delete from t1 where a=0; update t1 set a=NULL where b=13; Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'a' at row 9 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 9 update t1 set a=500 where b=14; select * from t1 order by b; a b diff --git a/mysql-test/r/convert.result b/mysql-test/r/convert.result deleted file mode 100644 index f8dad8c69ba..00000000000 --- a/mysql-test/r/convert.result +++ /dev/null @@ -1,17 +0,0 @@ -select @@convert_character_set; -@@convert_character_set - -select @@global.convert_character_set; -@@global.convert_character_set - -show variables like "%convert_character_set%"; -Variable_name Value -convert_character_set -SET CHARACTER SET cp1251_koi8; -select @@convert_character_set; -@@convert_character_set -cp1251_koi8 -SET CHARACTER SET DEFAULT; -select @@convert_character_set; -@@convert_character_set - diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 2f907880cbe..b51836f39e0 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -10,7 +10,7 @@ create table t1 (b char(0) not null); create table if not exists t1 (b char(0) not null); insert into t1 values (""),(null); Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'b' at row 2 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'b' at row 2 select * from t1; b @@ -193,7 +193,7 @@ SELECT @@table_type; GEMINI CREATE TABLE t1 (a int not null); Warnings: -Warning 1264 Using storage engine MYISAM for table 't1' +Warning 1265 Using storage engine MYISAM for table 't1' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -302,7 +302,7 @@ SELECT @@table_type; GEMINI CREATE TABLE t1 (a int not null); Warnings: -Warning 1264 Using storage engine MYISAM for table 't1' +Warning 1265 Using storage engine MYISAM for table 't1' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/r/ctype_latin1_de.result b/mysql-test/r/ctype_latin1_de.result index 7f116c1fc52..3db2f3d5519 100644 --- a/mysql-test/r/ctype_latin1_de.result +++ b/mysql-test/r/ctype_latin1_de.result @@ -1,3 +1,6 @@ +select @@collation_connection; +@@collation_connection +latin1_german2_ci drop table if exists t1; create table t1 (a char (20) not null, b int not null auto_increment, index (a,b)); insert into t1 (a) values ('ä'),('ac'),('ae'),('ad'),('Äc'),('aeb'); diff --git a/mysql-test/r/distinct.result b/mysql-test/r/distinct.result index 3c6769e797b..c7ce157a670 100644 --- a/mysql-test/r/distinct.result +++ b/mysql-test/r/distinct.result @@ -173,9 +173,9 @@ INSERT INTO t2 values (1),(2),(3); INSERT INTO t3 VALUES (1,'1'),(2,'2'),(1,'1'),(2,'2'); explain SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 2 Using temporary -1 SIMPLE t2 ref a a 4 test.t1.a 2 Using index +1 SIMPLE t1 ALL PRIMARY NULL NULL NULL 4 Using temporary 1 SIMPLE t3 ref a a 5 test.t1.b 2 Using where; Using index +1 SIMPLE t2 index a a 4 NULL 4 Using where; Using index; Distinct SELECT distinct t3.a FROM t3,t2,t1 WHERE t3.a=t1.b AND t1.a=t2.a; a 1 diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index 6029cc90d1d..367b28e9bf7 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -1,4 +1,5 @@ drop table if exists t1; +drop database if exists mysqltest; drop table t1; ERROR 42S02: Unknown table 't1' create table t1(n int); @@ -11,9 +12,6 @@ drop table t1; select * from t1; n 1 -drop database if exists mysqltest; -Warnings: -Note 1008 Can't drop database 'mysqltest'; database doesn't exist create database mysqltest; drop database if exists mysqltest; create database mysqltest; @@ -25,8 +23,6 @@ n drop database if exists mysqltest; create database mysqltest; drop database mysqltest; -Warnings: -Note 1008 Can't drop database 'mysqltest'; database doesn't exist flush tables with read lock; create database mysqltest; Got one of the listed errors diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index 157beec2c01..e2d35973383 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -23,6 +23,36 @@ a b Only MyISAM tables support collections Full-text indexes are called collections Full-text indexes are called collections +explain select * from t1 where MATCH(a,b) AGAINST ("collections"); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 Using where +explain select * from t1 where MATCH(a,b) AGAINST ("collections")>=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where +explain select * from t1 where 00 and a like '%ll%'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 fulltext a a 0 1 Using where select * from t1 where MATCH(a,b) AGAINST("support -collections" IN BOOLEAN MODE); a b MySQL has now support for full-text search @@ -97,6 +127,11 @@ select * from t1 where MATCH b AGAINST ("sear*" IN BOOLEAN MODE); a b MySQL has now support for full-text search Function MATCH ... AGAINST() is used to do a search +select * from t1 where MATCH(a,b) AGAINST ("collections") UNION ALL select * from t1 where MATCH(a,b) AGAINST ("indexes"); +a b +Only MyISAM tables support collections +Full-text indexes are called collections +Full-text indexes are called collections delete from t1 where a like "MySQL%"; update t1 set a='some test foobar' where MATCH a,b AGAINST ('model'); delete from t1 where MATCH(a,b) AGAINST ("indexes"); @@ -226,3 +261,14 @@ select ref_mag from t1 where match ref_mag against ('+test' in boolean mode); ref_mag test drop table t1; +create table t1 (t1_id int(11) primary key, name varchar(32)); +insert into t1 values (1, 'data1'); +insert into t1 values (2, 'data2'); +create table t2 (t2_id int(11) primary key, t1_id int(11), name varchar(32)); +insert into t2 values (1, 1, 'xxfoo'); +insert into t2 values (2, 1, 'xxbar'); +insert into t2 values (3, 1, 'xxbuz'); +select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode); +t1_id name t2_id t1_id name +1 data1 1 1 xxfoo +drop table t1,t2; diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 15b406bcdda..a4493e7c95c 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -148,10 +148,10 @@ grp group_concat(c) 4 5 NULL Warnings: -Warning 1258 1 line(s) was(were) cut by group_concat() +Warning 1259 1 line(s) was(were) cut by group_concat() show warnings; Level Code Message -Warning 1258 1 line(s) was(were) cut by group_concat() +Warning 1259 1 line(s) was(were) cut by group_concat() set group_concat_max_len = 1024; select group_concat(sum(a)) from t1 group by grp; ERROR HY000: Invalid use of group function diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index 06f63b525cd..82f68cdaa84 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -496,7 +496,7 @@ insert(_latin2'abcd',2,3,_latin2'ef'), replace(_latin2'abcd',_latin2'b',_latin2'B') ; Warnings: -Warning 1263 Data truncated for column 'format(130,10)' at row 1 +Warning 1264 Data truncated for column 'format(130,10)' at row 1 show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -571,9 +571,7 @@ elt(status_wnio,data_podp) NULL NULL DROP TABLE t1; -CREATE TABLE t1 ( -title text -) TYPE=MyISAM; +CREATE TABLE t1 (title text) TYPE=MyISAM; INSERT INTO t1 VALUES ('Congress reconvenes in September to debate welfare and adult education'); INSERT INTO t1 VALUES ('House passes the CAREERS bill'); SELECT CONCAT("",RPAD("",(55 - LENGTH(title)),".")) from t1; diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result index 9ae7b0c3ef1..e3a0d066a85 100644 --- a/mysql-test/r/func_test.result +++ b/mysql-test/r/func_test.result @@ -52,6 +52,20 @@ select 10 % 7, 10 mod 7, 10 div 3; select (1 << 64)-1, ((1 << 64)-1) DIV 1, ((1 << 64)-1) DIV 2; (1 << 64)-1 ((1 << 64)-1) DIV 1 ((1 << 64)-1) DIV 2 18446744073709551615 18446744073709551615 9223372036854775807 +create table t1 (a int); +insert t1 values (1); +select * from t1 where 1 xor 1; +a +drop table t1; +select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1; +5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1 +0 1 +select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1; +1 and 2 between 2 and 10 2 between 2 and 10 and 1 +1 1 +select 1 and 0 or 2, 2 or 1 and 0; +1 and 0 or 2 2 or 1 and 0 +1 1 select _koi8r'a' = _koi8r'A'; _koi8r'a' = _koi8r'A' 1 @@ -109,17 +123,3 @@ select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' COLLATE koi8r_bin; ERROR HY000: Illegal mix of collations (koi8r_general_ci,EXPLICIT) and (koi8r_bin,EXPLICIT) for operation 'like' select _koi8r'a' LIKE _latin1'A'; ERROR HY000: Illegal mix of collations (koi8r_general_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation 'like' -create table t1 (a int); -insert t1 values (1); -select * from t1 where 1 xor 1; -a -drop table t1; -select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1; -5 between 0 and 10 between 0 and 1 (5 between 0 and 10) between 0 and 1 -0 1 -select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1; -1 and 2 between 2 and 10 2 between 2 and 10 and 1 -1 1 -select 1 and 0 or 2, 2 or 1 and 0; -1 and 0 or 2 2 or 1 and 0 -1 1 diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 09c2b2042b3..7d3aeb62227 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1,5 +1,4 @@ drop table if exists t1; -create table t1 (a int); delete from mysql.user where user='mysqltest_1'; delete from mysql.db where user='mysqltest_1'; flush privileges; @@ -108,4 +107,41 @@ delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; drop table t1; GRANT FILE on mysqltest.* to mysqltest_1@localhost; -Wrong usage of DB GRANT and GLOBAL PRIVILEGES +ERROR HY000: Wrong usage of DB GRANT and GLOBAL PRIVILEGES +select 1; +1 +1 +create table t1 (a int); +grant ALL PRIVILEGES on *.* to drop_user2@localhost with GRANT OPTION; +show grants for drop_user2@localhost; +Grants for drop_user2@localhost +GRANT ALL PRIVILEGES ON *.* TO 'drop_user2'@'localhost' WITH GRANT OPTION +revoke all privileges, grant from drop_user2@localhost; +drop user drop_user2@localhost; +grant ALL PRIVILEGES on *.* to drop_user@localhost with GRANT OPTION; +grant ALL PRIVILEGES on test.* to drop_user@localhost with GRANT OPTION; +grant select(a) on test.t1 to drop_user@localhost; +show grants for drop_user@localhost; +Grants for drop_user@localhost +GRANT ALL PRIVILEGES ON *.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT ALL PRIVILEGES ON `test`.* TO 'drop_user'@'localhost' WITH GRANT OPTION +GRANT SELECT (a) ON `test`.`t1` TO 'drop_user'@'localhost' +revoke all privileges, grant from drop_user@localhost; +show grants for drop_user@localhost; +Grants for drop_user@localhost +GRANT USAGE ON *.* TO 'drop_user'@'localhost' +drop user drop_user@localhost; +revoke all privileges, grant from drop_user@localhost; +ERROR HY000: Can't revoke all privileges, grant for one or more of the requested users +grant select(a) on test.t1 to drop_user1@localhost; +grant select on test.t1 to drop_user2@localhost; +grant select on test.* to drop_user3@localhost; +grant select on *.* to drop_user4@localhost; +drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, +drop_user4@localhost; +ERROR HY000: Can't drop one or more of the requested users +revoke all privileges, grant from drop_user1@localhost, drop_user2@localhost, +drop_user3@localhost, drop_user4@localhost; +drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, +drop_user4@localhost; +drop table t1; diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result index de0407a8907..3cb9c59cc57 100644 --- a/mysql-test/r/group_by.result +++ b/mysql-test/r/group_by.result @@ -115,7 +115,7 @@ groupset bigint(20) DEFAULT '0' NOT NULL, assigned_to mediumint(9) DEFAULT '0' NOT NULL, bug_file_loc text, bug_severity enum('blocker','critical','major','normal','minor','trivial','enhancement') DEFAULT 'blocker' NOT NULL, -bug_status enum('NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED') DEFAULT 'NEW' NOT NULL, +bug_status enum('','NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED') DEFAULT 'NEW' NOT NULL, creation_ts datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, delta_ts timestamp(14), short_desc mediumtext, @@ -150,92 +150,34 @@ KEY qa_contact (qa_contact), KEY votes (votes) ); INSERT INTO t1 VALUES (1,0,0,'','normal','','2000-02-10 09:25:12',20000321114747,'','','Linux','P1','TestProduct','PC',3,'other','TestComponent','','M1',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (9,0,0,'','enhancement','','2000-03-10 11:49:36',20000321114747,'','','All','P5','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - conversion','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (10,0,0,'','enhancement','','2000-03-10 18:10:16',20000321114747,'','','All','P4','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - conversion','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (7,0,0,'','critical','','2000-03-09 10:50:21',20000321114747,'','','All','P1','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - generic','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (6,0,0,'','normal','','2000-03-09 10:42:44',20000321114747,'','','All','P2','AAAAA','PC',3,'2.00 CD - Pre','kkkkkkkkkkk lllllllllll','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (8,0,0,'','major','','2000-03-09 11:32:14',20000321114747,'','','All','P3','AAAAA','PC',3,'2.00 CD - Pre','kkkkkkkkkkk lllllllllll','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (5,0,0,'','enhancement','','2000-03-09 10:38:59',20000321114747,'','','All','P5','CCC/CCCCCC','PC',5,'7.00','Administration','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (4,0,0,'','normal','','2000-03-08 18:32:14',20000321114747,'','','other','P2','TestProduct','Other',3,'other','TestComponent2','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (3,0,0,'','normal','','2000-03-08 18:30:52',20000321114747,'','','other','P2','TestProduct','Other',3,'other','TestComponent','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (2,0,0,'','enhancement','','2000-03-08 18:24:51',20000321114747,'','','All','P2','TestProduct','Other',4,'other','TestComponent2','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (11,0,0,'','blocker','','2000-03-13 09:43:41',20000321114747,'','','All','P2','CCC/CCCCCC','PC',5,'7.00','DDDDDDDDD','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (12,0,0,'','normal','','2000-03-13 16:14:31',20000321114747,'','','All','P2','AAAAA','PC',3,'2.00 CD - Pre','kkkkkkkkkkk lllllllllll','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (13,0,0,'','normal','','2000-03-15 16:20:44',20000321114747,'','','other','P2','TestProduct','Other',3,'other','TestComponent','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (14,0,0,'','blocker','','2000-03-15 18:13:47',20000321114747,'','','All','P1','AAAAA','PC',3,'2.00 CD - Pre','BBBBBBBBBBBBB - generic','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (15,0,0,'','minor','','2000-03-16 18:03:28',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','DDDDDDDDD','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (16,0,0,'','normal','','2000-03-16 18:33:41',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (17,0,0,'','normal','','2000-03-16 18:34:18',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (18,0,0,'','normal','','2000-03-16 18:34:56',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (19,0,0,'','enhancement','','2000-03-16 18:35:34',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (20,0,0,'','enhancement','','2000-03-16 18:36:23',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (21,0,0,'','enhancement','','2000-03-16 18:37:23',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (22,0,0,'','enhancement','','2000-03-16 18:38:16',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','Administration','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (23,0,0,'','normal','','2000-03-16 18:58:12',20000321114747,'','','All','P2','CCC/CCCCCC','Other',5,'7.00','DDDDDDDDD','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (24,0,0,'','normal','','2000-03-17 11:08:10',20000321114747,'','','All','P2','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (25,0,0,'','normal','','2000-03-17 11:10:45',20000321114747,'','','All','P2','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (26,0,0,'','normal','','2000-03-17 11:15:47',20000321114747,'','','All','P2','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (27,0,0,'','normal','','2000-03-17 17:45:41',20000321114747,'','','All','P2','CCC/CCCCCC','PC',5,'7.00','DDDDDDDDD','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (28,0,0,'','normal','','2000-03-20 09:51:45',20000321114747,'','','Windows NT','P2','TestProduct','PC',8,'other','TestComponent','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 INSERT INTO t1 VALUES (29,0,0,'','normal','','2000-03-20 11:15:09',20000321114747,'','','All','P5','AAAAAAAA-AAA','PC',3,'2.8','Web Interface','','',0,'',0); -Warnings: -Warning 1263 Data truncated for column 'bug_status' at row 1 CREATE TABLE t2 ( value tinytext, program varchar(64), diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index bf68057a9aa..78ccf941b88 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -167,30 +167,11 @@ handler t1 read first; a 6 drop table t1; -create table t1 (a int); -insert into t1 values (1),(2),(3),(4),(5),(6); -delete from t1 limit 2; -handler t1 open; -handler t1 read first; -a -3 -handler t1 read first limit 1,1; -a -4 -handler t1 read first limit 2,2; -a -5 -6 -delete from t1 limit 3; -handler t1 read first; -a -6 -drop table t1; create table t1(a int, index(a)); insert into t1 values (1), (2), (3); handler t1 open; handler t1 read a=(W); -Unknown column 'W' in 'field list' +ERROR 42S22: Unknown column 'W' in 'field list' handler t1 read a=(a); -Wrong arguments to HANDLER ... READ +ERROR HY000: Wrong arguments to HANDLER ... READ drop table t1; diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result index 4f73cfb6d72..6c5ef8f3441 100644 --- a/mysql-test/r/heap.result +++ b/mysql-test/r/heap.result @@ -163,13 +163,7 @@ id select_type table type possible_keys key key_len ref rows Extra select * from t1 where btn like "q%"; btn alter table t1 add column new_col char(1) not null, add key (btn,new_col), drop key btn; -update t1 set new_col=btn; -Warnings: -Warning 1263 Data truncated for column 'new_col' at row 1 -Warning 1263 Data truncated for column 'new_col' at row 2 -Warning 1263 Data truncated for column 'new_col' at row 3 -Warning 1263 Data truncated for column 'new_col' at row 4 -Warning 1263 Data truncated for column 'new_col' at row 5 +update t1 set new_col=left(btn,1); explain select * from t1 where btn="a"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL btn NULL NULL NULL 11 Using where @@ -209,8 +203,8 @@ key a (a) ) TYPE=HEAP; INSERT INTO t1 VALUES (10), (10), (10); EXPLAIN SELECT * FROM t1 WHERE a=10; -table type possible_keys key key_len ref rows Extra -t1 ref a a 5 const 10 Using where +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref a a 5 const 10 Using where SELECT * FROM t1 WHERE a=10; a 10 diff --git a/mysql-test/r/heap_btree.result b/mysql-test/r/heap_btree.result index 1ba8d429fc4..c42c5e60675 100644 --- a/mysql-test/r/heap_btree.result +++ b/mysql-test/r/heap_btree.result @@ -179,13 +179,7 @@ id select_type table type possible_keys key key_len ref rows Extra select * from t1 where btn like "q%"; btn alter table t1 add column new_col char(1) not null, add key using BTREE (btn,new_col), drop key btn; -update t1 set new_col=btn; -Warnings: -Warning 1263 Data truncated for column 'new_col' at row 1 -Warning 1263 Data truncated for column 'new_col' at row 2 -Warning 1263 Data truncated for column 'new_col' at row 3 -Warning 1263 Data truncated for column 'new_col' at row 4 -Warning 1263 Data truncated for column 'new_col' at row 5 +update t1 set new_col=left(btn,1); explain select * from t1 where btn="a"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref btn btn 10 const 1 Using where diff --git a/mysql-test/r/heap_hash.result b/mysql-test/r/heap_hash.result index 72278c5da67..7ecd1db7447 100644 --- a/mysql-test/r/heap_hash.result +++ b/mysql-test/r/heap_hash.result @@ -163,16 +163,10 @@ id select_type table type possible_keys key key_len ref rows Extra select * from t1 where btn like "q%"; btn alter table t1 add column new_col char(1) not null, add key using HASH (btn,new_col), drop key btn; -update t1 set new_col=btn; -Warnings: -Warning 1263 Data truncated for column 'new_col' at row 1 -Warning 1263 Data truncated for column 'new_col' at row 2 -Warning 1263 Data truncated for column 'new_col' at row 3 -Warning 1263 Data truncated for column 'new_col' at row 4 -Warning 1263 Data truncated for column 'new_col' at row 5 +update t1 set new_col=left(btn,1); explain select * from t1 where btn="a"; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL btn NULL NULL NULL 14 Using where +1 SIMPLE t1 ALL btn NULL NULL NULL 11 Using where explain select * from t1 where btn="a" and new_col="a"; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref btn btn 11 const,const 10 Using where diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 69268f1d5c5..8592393fd42 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1,4 +1,5 @@ drop table if exists t1,t2,t3; +drop database if exists mysqltest; create table t1 (id int unsigned not null auto_increment, code tinyint unsigned not null, name char(20) not null, primary key (id), key (code), unique (name)) type=innodb; insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'), (2, 'Erik'), (3, 'Sasha'), (3, 'Jeremy'), (4, 'Matt'); select id, code, name from t1 order by id; @@ -138,6 +139,15 @@ id parent_id level 1008 102 2 1010 102 2 1015 102 2 +explain select level from t1 where level=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref level level 1 const # Using where; Using index +explain select level,id from t1 where level=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref level level 1 const # Using where; Using index +explain select level,id,parent_id from t1 where level=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref level level 1 const # Using where select level,id from t1 where level=1; level id 1 1002 @@ -156,7 +166,7 @@ level id parent_id 1 1007 101 optimize table t1; Table Op Msg_type Msg_text -test.t1 optimize error The storage engine for the table doesn't support optimize +test.t1 optimize status OK show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment t1 0 PRIMARY 1 id A # NULL NULL BTREE @@ -180,7 +190,7 @@ create table t1 (a int) type=innodb; insert into t1 values (1), (2); optimize table t1; Table Op Msg_type Msg_text -test.t1 optimize error The storage engine for the table doesn't support optimize +test.t1 optimize status OK delete from t1 where a = 1; select * from t1; a @@ -202,7 +212,7 @@ Table Op Msg_type Msg_text test.t1 analyze status OK show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t1 1 skr 1 a A 3 NULL NULL YES BTREE +t1 1 skr 1 a A # NULL NULL YES BTREE drop table t1; create table t1 (a int,b varchar(20),key(a)) type=innodb; insert into t1 values (1,""), (2,"testing"); @@ -345,12 +355,12 @@ CREATE TABLE t1 (a int not null, b int not null,c int not null, key(a),primary key(a,b), unique(c),key(a),unique(b)); show index from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t1 0 PRIMARY 1 a A NULL NULL NULL BTREE -t1 0 PRIMARY 2 b A 0 NULL NULL BTREE -t1 0 c 1 c A 0 NULL NULL BTREE -t1 0 b 1 b A 0 NULL NULL BTREE -t1 1 a 1 a A NULL NULL NULL BTREE -t1 1 a_2 1 a A NULL NULL NULL BTREE +t1 0 PRIMARY 1 a A # NULL NULL BTREE +t1 0 PRIMARY 2 b A # NULL NULL BTREE +t1 0 c 1 c A # NULL NULL BTREE +t1 0 b 1 b A # NULL NULL BTREE +t1 1 a 1 a A # NULL NULL BTREE +t1 1 a_2 1 a A # NULL NULL BTREE drop table t1; create table t1 (col1 int not null, col2 char(4) not null, primary key(col1)); alter table t1 type=innodb; @@ -586,6 +596,9 @@ id parent_id level 1009 102 2 1025 102 2 1016 102 2 +explain select level from t1 where level=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref level level 1 const # Using where; Using index select level,id from t1 where level=1; level id 1 1004 @@ -712,10 +725,10 @@ world 2 hello 1 optimize table t1; Table Op Msg_type Msg_text -test.t1 optimize error The storage engine for the table doesn't support optimize +test.t1 optimize status OK show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -t1 0 PRIMARY 1 a A 2 NULL NULL BTREE +t1 0 PRIMARY 1 a A # NULL NULL BTREE drop table t1; create table t1 (i int, j int ) TYPE=innodb; insert into t1 values (1,2); @@ -747,7 +760,7 @@ create table t1 (a int primary key,b int, c int, d int, e int, f int, g int, h insert into t1 values (1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1); explain select * from t1 where a > 0 and a < 50; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 1 Using where +1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL # Using where drop table t1; create table t1 (id int NOT NULL,id2 int NOT NULL,id3 int NOT NULL,dummy1 char(30),primary key (id,id2),index index_id3 (id3)) type=innodb; insert into t1 values (0,0,0,'ABCDEFGHIJ'),(2,2,2,'BCDEFGHIJK'),(1,1,1,'CDEFGHIJKL'); @@ -788,13 +801,13 @@ id id3 UNLOCK TABLES; DROP TABLE t1; create table t1 (a char(20), unique (a(5))) type=innodb; -ERROR HY000: Incorrect sub part key. The used key part isn't a string, the used length is longer than the key part or the storage engine doesn't support unique sub keys +drop table t1; create table t1 (a char(20), index (a(5))) type=innodb; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` char(20) default NULL, - KEY `a` (`a`) + KEY `a` (`a`(5)) ) TYPE=InnoDB CHARSET=latin1 drop table t1; create temporary table t1 (a int not null auto_increment, primary key(a)) type=innodb; @@ -881,28 +894,28 @@ create table t1 (a int not null, b int not null, c int not null, primary key (a) insert into t1 values (3,3,3),(1,1,1),(2,2,2),(4,4,4); explain select * from t1 order by a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 +1 SIMPLE t1 index NULL PRIMARY 4 NULL # explain select * from t1 order by b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL b 4 NULL 4 +1 SIMPLE t1 index NULL b 4 NULL # explain select * from t1 order by c; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using filesort +1 SIMPLE t1 ALL NULL NULL NULL NULL # Using filesort explain select a from t1 order by a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL PRIMARY 4 NULL 4 Using index +1 SIMPLE t1 index NULL PRIMARY 4 NULL # Using index explain select b from t1 order by b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL b 4 NULL 4 Using index +1 SIMPLE t1 index NULL b 4 NULL # Using index explain select a,b from t1 order by b; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL b 4 NULL 4 Using index +1 SIMPLE t1 index NULL b 4 NULL # Using index explain select a,b from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 index NULL b 4 NULL 4 Using index +1 SIMPLE t1 index NULL b 4 NULL # Using index explain select a,b,c from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 4 +1 SIMPLE t1 ALL NULL NULL NULL NULL # drop table t1; create table t1 (t int not null default 1, key (t)) type=innodb; desc t1; @@ -1249,11 +1262,11 @@ count(*) 29267 explain select * from t1 where c between 1 and 10000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range c c 5 NULL 1 Using where +1 SIMPLE t1 range c c 5 NULL # Using where update t1 set c=a; explain select * from t1 where c between 1 and 10000; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL c NULL NULL NULL 29537 Using where +1 SIMPLE t1 ALL c NULL NULL NULL # Using where drop table t1,t2; create table t1 (id int primary key auto_increment, fk int, index index_fk (fk)) type=innodb; insert into t1 (id) values (null),(null),(null),(null),(null); diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result index 59c598265c0..b84c846b132 100644 --- a/mysql-test/r/insert.result +++ b/mysql-test/r/insert.result @@ -60,8 +60,10 @@ test 2 drop table t1; create table t1 (id int NOT NULL DEFAULT 8); insert into t1 values(NULL); -Column 'id' cannot be null +ERROR 23000: Column 'id' cannot be null insert into t1 values (1), (NULL), (2); +Warnings: +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'id' at row 2 select * from t1; id 1 diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index d5b9b9a2117..82d5ee872a2 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -64,7 +64,7 @@ bulk_insert_buffer_size 8388608 INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip) SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM t2 WHERE numeropost=9 ORDER BY numreponse ASC; -DROP TABLE IF EXISTS t1,t2; +DROP TABLE t1,t2; create table t1(a int, unique(a)); insert into t1 values(2); create table t2(a int); @@ -76,7 +76,6 @@ show binlog events; Log_name Pos Event_type Server_id Orig_log_pos Info master-bin.000001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3 drop table t1, t2; -drop table if exists t1, t2; create table t1 (a int not null); create table t2 (a int not null); insert into t1 values (1); @@ -566,14 +565,14 @@ a 5 5 insert into t1 select * from t1,t1; -Not unique table/alias: 't1' +ERROR 42000: Not unique table/alias: 't1' drop table t1,t2; create table t1 (a int not null primary key, b char(10)); create table t2 (a int not null, b char(10)); insert into t1 values (1,"t1:1"),(3,"t1:3"); insert into t2 values (2,"t2:2"), (3,"t2:3"); insert into t1 select * from t2; -Duplicate entry '3' for key 1 +ERROR 23000: Duplicate entry '3' for key 1 select * from t1; a b 1 t1:1 diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index b7d3f94cb33..b060fdfb85c 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -663,5 +663,5 @@ create table t3 (f3 integer,f5 integer); select * from t1 left outer join t2 using (f2) left outer join t3 using (f3); -Unknown column 'test.t2.f3' in 'on clause' +ERROR 42S22: Unknown column 'test.t2.f3' in 'on clause' drop table t1,t2,t3; diff --git a/mysql-test/r/key.result b/mysql-test/r/key.result index e0b2b84ac16..89deab4bb1f 100644 --- a/mysql-test/r/key.result +++ b/mysql-test/r/key.result @@ -1,4 +1,5 @@ drop table if exists t1,t2,t3; +SET SQL_WARNINGS=1; CREATE TABLE t1 ( ID CHAR(32) NOT NULL, name CHAR(32) NOT NULL, @@ -33,10 +34,10 @@ INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','N','N','N','N'); INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','N','N','N','N'); INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','','','',''); Warnings: -Warning 1263 Data truncated for column 'transityes' at row 1 -Warning 1263 Data truncated for column 'shopsyes' at row 1 -Warning 1263 Data truncated for column 'schoolsyes' at row 1 -Warning 1263 Data truncated for column 'petsyes' at row 1 +Warning 1264 Data truncated for column 'transityes' at row 1 +Warning 1264 Data truncated for column 'shopsyes' at row 1 +Warning 1264 Data truncated for column 'schoolsyes' at row 1 +Warning 1264 Data truncated for column 'petsyes' at row 1 INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y'); INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y'); INSERT INTO t1 VALUES (900,'Vancouver','Shared/Roomate','Y','Y','Y','Y'); @@ -94,13 +95,9 @@ INSERT t1 VALUES(NULL,'/'); INSERT t1 VALUES(NULL,'[T,U]_axpby'); SELECT * FROM t1 WHERE name='[T,U]_axpy'; name_id name -Warnings: -Warning 1263 Data truncated for column 'name' at row 1 SELECT * FROM t1 WHERE name='[T,U]_axpby'; name_id name 2 [T,U]_axpby -Warnings: -Warning 1263 Data truncated for column 'name' at row 1 create table t2 ( name_id int not null auto_increment, @@ -159,8 +156,8 @@ CREATE TABLE t1 (c CHAR(10) NOT NULL,i INT NOT NULL AUTO_INCREMENT, UNIQUE (c,i)); INSERT INTO t1 (c) VALUES (NULL),(NULL); Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'c' at row 1 -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'c' at row 2 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'c' at row 1 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'c' at row 2 SELECT * FROM t1; c i 1 diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result index 8ec507b2a3f..dd45cb51d33 100644 --- a/mysql-test/r/key_cache.result +++ b/mysql-test/r/key_cache.result @@ -35,7 +35,7 @@ SELECT @@small.key_buffer_size; 1048576 SELECT @@medium.key_buffer_size; @@medium.key_buffer_size -4194304 +0 SET @@global.key_buffer_size=@save_key_buffer; SELECT @@default.key_buffer_size; ERROR 42000: You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'default.key_buffer_size' at line 1 diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index 3cd62d8b678..508e1844d84 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -2,12 +2,12 @@ drop table if exists t1; create table t1 (a date, b date, c date not null, d date); load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ','; Warnings: -Warning 1263 Data truncated for column 'a' at row 1 -Warning 1263 Data truncated for column 'c' at row 1 -Warning 1263 Data truncated for column 'd' at row 1 -Warning 1263 Data truncated for column 'a' at row 2 -Warning 1263 Data truncated for column 'b' at row 2 -Warning 1263 Data truncated for column 'd' at row 2 +Warning 1264 Data truncated for column 'a' at row 1 +Warning 1264 Data truncated for column 'c' at row 1 +Warning 1264 Data truncated for column 'd' at row 1 +Warning 1264 Data truncated for column 'a' at row 2 +Warning 1264 Data truncated for column 'b' at row 2 +Warning 1264 Data truncated for column 'd' at row 2 load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES; SELECT * from t1; a b c d @@ -18,10 +18,10 @@ a b c d truncate table t1; load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' LINES STARTING BY ',' (b,c,d); Warnings: -Warning 1263 Data truncated for column 'c' at row 1 -Warning 1263 Data truncated for column 'd' at row 1 -Warning 1263 Data truncated for column 'b' at row 2 -Warning 1263 Data truncated for column 'd' at row 2 +Warning 1264 Data truncated for column 'c' at row 1 +Warning 1264 Data truncated for column 'd' at row 1 +Warning 1264 Data truncated for column 'b' at row 2 +Warning 1264 Data truncated for column 'd' at row 2 SELECT * from t1; a b c d NULL NULL 0000-00-00 0000-00-00 diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 59af9b3e7f3..d158c39cba8 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -1,4 +1,5 @@ drop table if exists t1,t2; +SET SQL_WARNINGS=1; CREATE TABLE t1 ( STRING_DATA char(255) default NULL, KEY string_data (STRING_DATA) @@ -14,34 +15,6 @@ Table Op Msg_type Msg_text test.t1 check status OK drop table t1; create table t1 (a tinyint not null auto_increment, b blob not null, primary key (a)); -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warnings: -Warning 1263 Data truncated for column 'b' at row 1 check table t1; Table Op Msg_type Msg_text test.t1 check status OK @@ -361,8 +334,8 @@ t1 1 c_2 1 c A 5 NULL NULL YES BTREE t1 1 c_2 2 a A 5 NULL NULL BTREE explain select * from t1,t2 where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL a NULL NULL NULL 2 Using where -1 SIMPLE t1 ALL a NULL NULL NULL 4 +1 SIMPLE t2 ALL a NULL NULL NULL 2 +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where explain select * from t1,t2 force index(a) where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL a NULL NULL NULL 2 @@ -377,8 +350,8 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref b b 5 test.t2.b 1 Using where explain select * from t1,t2 force index(c) where t1.a=t2.a; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where -1 SIMPLE t1 ALL a NULL NULL NULL 4 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 +1 SIMPLE t1 ALL a NULL NULL NULL 4 Using where explain select * from t1 where a=0 or a=2; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL a NULL NULL NULL 5 Using where diff --git a/mysql-test/r/null.result b/mysql-test/r/null.result index 0dd9754d0c5..479a7f049d9 100644 --- a/mysql-test/r/null.result +++ b/mysql-test/r/null.result @@ -77,42 +77,42 @@ CREATE TABLE t1 (a varchar(16) NOT NULL, b smallint(6) NOT NULL, c datetime NOT INSERT INTO t1 SET a = "", d= "2003-01-14 03:54:55"; UPDATE t1 SET d=1/NULL; Warnings: -Warning 1263 Data truncated for column 'd' at row 1 +Warning 1264 Data truncated for column 'd' at row 1 UPDATE t1 SET d=NULL; Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'd' at row 1 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'd' at row 1 INSERT INTO t1 (a) values (null); ERROR 23000: Column 'a' cannot be null INSERT INTO t1 (a) values (1/null); ERROR 23000: Column 'a' cannot be null INSERT INTO t1 (a) values (null),(null); Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'a' at row 1 -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'a' at row 2 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 1 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 2 INSERT INTO t1 (b) values (null); ERROR 23000: Column 'b' cannot be null INSERT INTO t1 (b) values (1/null); ERROR 23000: Column 'b' cannot be null INSERT INTO t1 (b) values (null),(null); Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'b' at row 1 -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'b' at row 2 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'b' at row 1 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'b' at row 2 INSERT INTO t1 (c) values (null); ERROR 23000: Column 'c' cannot be null INSERT INTO t1 (c) values (1/null); ERROR 23000: Column 'c' cannot be null INSERT INTO t1 (c) values (null),(null); Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'c' at row 1 -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'c' at row 2 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'c' at row 1 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'c' at row 2 INSERT INTO t1 (d) values (null); ERROR 23000: Column 'd' cannot be null INSERT INTO t1 (d) values (1/null); ERROR 23000: Column 'd' cannot be null INSERT INTO t1 (d) values (null),(null); Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'd' at row 1 -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'd' at row 2 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'd' at row 1 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'd' at row 2 select * from t1; a b c d 0 0000-00-00 00:00:00 0 diff --git a/mysql-test/r/null_key.result b/mysql-test/r/null_key.result index 7dc0b4bfdd3..9aaea0d800b 100644 --- a/mysql-test/r/null_key.result +++ b/mysql-test/r/null_key.result @@ -153,7 +153,7 @@ a b 7 NULL explain select * from t1 where (a = 7 or a is null) and (b=7 or b is null); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a,b a 10 NULL 4 Using where; Using index +1 SIMPLE t1 range a,b a 10 NULL 3 Using where; Using index select * from t1 where (a = 7 or a is null) and (b=7 or b is null); a b NULL 7 @@ -337,7 +337,7 @@ index (id2) ); insert into t1 values(null,null),(1,1); Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'id2' at row 1 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'id2' at row 1 select * from t1; id id2 NULL 0 diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 5470b9387e3..79ccf833f40 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -306,17 +306,17 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 9 NULL 8 Using where; Using index explain select * from t1 where a = 2 and b >0 order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 4 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index explain select * from t1 where a = 2 and b is null order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref a a 9 const,const 1 Using where; Using index; Using filesort explain select * from t1 where a = 2 and (b is null or b > 0) order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 6 Using where; Using index explain select * from t1 where a = 2 and b > 0 order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 9 NULL 4 Using where; Using index +1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index explain select * from t1 where a = 2 and b < 2 order by a desc,b desc; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 9 NULL 2 Using where; Using index @@ -333,10 +333,10 @@ a b c 1 NULL NULL alter table t1 modify b int not null, modify c varchar(10) not null; Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warning 1263 Data truncated for column 'c' at row 1 -Warning 1263 Data truncated for column 'b' at row 2 -Warning 1263 Data truncated for column 'c' at row 3 +Warning 1264 Data truncated for column 'b' at row 1 +Warning 1264 Data truncated for column 'c' at row 1 +Warning 1264 Data truncated for column 'b' at row 2 +Warning 1264 Data truncated for column 'c' at row 3 explain select * from t1 order by a, b, c; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL a 18 NULL 11 Using index diff --git a/mysql-test/r/rpl_do_grant.result b/mysql-test/r/rpl_do_grant.result index fec935ae7ac..983cdf46620 100644 --- a/mysql-test/r/rpl_do_grant.result +++ b/mysql-test/r/rpl_do_grant.result @@ -1,9 +1,9 @@ -slave stop; +stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; +start slave; delete from mysql.user where user='rpl_do_grant'; delete from mysql.db where user='rpl_do_grant'; flush privileges; diff --git a/mysql-test/r/rpl_error_ignored_table.result b/mysql-test/r/rpl_error_ignored_table.result index e1486220542..f22b62838bb 100644 --- a/mysql-test/r/rpl_error_ignored_table.result +++ b/mysql-test/r/rpl_error_ignored_table.result @@ -1,15 +1,15 @@ -slave stop; +stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; +start slave; create table t1 (a int primary key); insert into t1 values (1),(1); -Duplicate entry '1' for key 1 +ERROR 23000: Duplicate entry '1' for key 1 show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 213 slave-relay-bin.002 254 master-bin.001 Yes Yes 0 0 213 254 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 213 slave-relay-bin.000002 257 master-bin.000001 Yes Yes test.t1 0 0 213 257 show tables like 't1'; Tables_in_test (t1) drop table t1; diff --git a/mysql-test/r/rpl_ignore_grant.result b/mysql-test/r/rpl_ignore_grant.result index 6cd7d5b4c00..5e970e71d0b 100644 --- a/mysql-test/r/rpl_ignore_grant.result +++ b/mysql-test/r/rpl_ignore_grant.result @@ -1,9 +1,9 @@ -slave stop; +stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; +start slave; delete from mysql.user where user='rpl_ignore_grant'; delete from mysql.db where user='rpl_ignore_grant'; flush privileges; @@ -17,7 +17,7 @@ Grants for rpl_ignore_grant@localhost GRANT SELECT ON *.* TO 'rpl_ignore_grant'@'localhost' GRANT DROP ON `test`.* TO 'rpl_ignore_grant'@'localhost' show grants for rpl_ignore_grant@localhost; -There is no such grant defined for user 'rpl_ignore_grant' on host 'localhost' +ERROR 42000: There is no such grant defined for user 'rpl_ignore_grant' on host 'localhost' select count(*) from mysql.user where user='rpl_ignore_grant'; count(*) 0 diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index fb3921eb677..55dcf2f4f0f 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -28,8 +28,8 @@ load data infile '../../std_data/rpl_loaddata.dat' into table t1; set global sql_slave_skip_counter=1; start slave; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 1311 slave-relay-bin.002 1352 master-bin.001 Yes Yes 0 0 1311 1352 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 1311 slave-relay-bin.000002 1355 master-bin.000001 Yes Yes 0 0 1311 1355 set sql_log_bin=0; delete from t1; set sql_log_bin=1; @@ -38,8 +38,8 @@ stop slave; change master to master_user='test'; change master to master_user='root'; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 1442 slave-relay-bin.001 4 master-bin.001 No No 0 0 1442 4 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 1442 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 1442 4 set global sql_slave_skip_counter=1; start slave; set sql_log_bin=0; @@ -49,5 +49,5 @@ load data infile '../../std_data/rpl_loaddata.dat' into table t1; stop slave; reset slave; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4 +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 +127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 050e9274a99..ab45826a3e7 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -93,6 +93,6 @@ slave-bin.000002 62 Query 1 168 use `test`; insert into t1 values (1) slave-bin.000002 122 Query 1 228 use `test`; drop table t1 show slave status; 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 -127.0.0.1 root MASTER_PORT 1 master-bin.000002 276 slave-relay-bin.000002 1531 master-bin.000002 Yes Yes 0 0 276 1535 +127.0.0.1 root MASTER_PORT 1 master-bin.000002 276 slave-relay-bin.000003 214 master-bin.000002 Yes Yes 0 0 276 214 show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log diff --git a/mysql-test/r/rpl_log_pos.result b/mysql-test/r/rpl_log_pos.result index b42e7ff5dc4..bc655b9b15a 100644 --- a/mysql-test/r/rpl_log_pos.result +++ b/mysql-test/r/rpl_log_pos.result @@ -9,7 +9,7 @@ File Position Binlog_do_db Binlog_ignore_db master-bin.000001 79 show slave status; 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 -127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 127 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 stop slave; change master to master_log_pos=73; start slave; @@ -21,7 +21,7 @@ Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Lo start slave; show slave status; 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 -127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 4 master-bin.000001 No Yes 0 0 73 4 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 73 slave-relay-bin.000001 48 master-bin.000001 No Yes 0 0 73 48 stop slave; change master to master_log_pos=173; start slave; diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result index 1fa3fcd1adb..741b3538799 100644 --- a/mysql-test/r/rpl_max_relay_size.result +++ b/mysql-test/r/rpl_max_relay_size.result @@ -1,9 +1,9 @@ -slave stop; +stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; +start slave; stop slave; create table t1 (a int); drop table t1; @@ -15,8 +15,8 @@ select @@global.max_relay_log_size; 4096 start slave; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.014 1221 master-bin.001 Yes Yes 0 0 50477 1221 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000014 1221 master-bin.000001 Yes Yes 0 0 50477 1221 stop slave; reset slave; set global max_relay_log_size=(5*4096); @@ -25,8 +25,8 @@ select @@global.max_relay_log_size; 20480 start slave; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.004 9457 master-bin.001 Yes Yes 0 0 50477 9457 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000004 9457 master-bin.000001 Yes Yes 0 0 50477 9457 stop slave; reset slave; set global max_relay_log_size=0; @@ -35,27 +35,27 @@ select @@global.max_relay_log_size; 0 start slave; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 50477 slave-relay-bin.008 1283 master-bin.001 Yes Yes 0 0 50477 1283 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 50477 slave-relay-bin.000008 1283 master-bin.000001 Yes Yes 0 0 50477 1283 stop slave; reset slave; flush logs; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4 +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 +127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 reset slave; start slave; flush logs; create table t1 (a int); show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 50535 slave-relay-bin.009 62 master-bin.001 Yes Yes 0 0 50535 62 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 50535 slave-relay-bin.000009 62 master-bin.000001 Yes Yes 0 0 50535 62 flush logs; drop table t1; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 50583 slave-relay-bin.010 52 master-bin.001 Yes Yes 0 0 50583 52 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 50583 slave-relay-bin.000010 52 master-bin.000001 Yes Yes 0 0 50583 52 flush logs; show master status; File Position Binlog_do_db Binlog_ignore_db -master-bin.002 4 +master-bin.000002 4 diff --git a/mysql-test/r/rpl_replicate_do.result b/mysql-test/r/rpl_replicate_do.result index 4d740cafbd0..ad92ee5b491 100644 --- a/mysql-test/r/rpl_replicate_do.result +++ b/mysql-test/r/rpl_replicate_do.result @@ -28,4 +28,4 @@ ERROR 42S02: Table 'test.t11' doesn't exist drop table if exists t1,t2,t11; show slave status; 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 -127.0.0.1 root MASTER_PORT 1 master-bin.000001 1281 slave-relay-bin.000002 1325 master-bin.000001 Yes Yes test.t1 0 0 1281 1329 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 1281 slave-relay-bin.000002 1325 master-bin.000001 Yes Yes test.t1 0 0 1281 1325 diff --git a/mysql-test/r/rpl_reset_slave.result b/mysql-test/r/rpl_reset_slave.result index c1bc1e8e483..239c4158410 100644 --- a/mysql-test/r/rpl_reset_slave.result +++ b/mysql-test/r/rpl_reset_slave.result @@ -1,22 +1,22 @@ -slave stop; +stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; +start slave; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 stop slave; change master to master_user='test'; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 test MASTER_PORT 1 master-bin.001 79 slave-relay-bin.001 4 master-bin.001 No No 0 0 79 4 +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 +127.0.0.1 test MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 79 4 reset slave; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.001 4 No No 0 0 0 4 +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 +127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 start slave; show slave status; -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 Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.001 79 slave-relay-bin.002 120 master-bin.001 Yes Yes 0 0 79 120 +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 +127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index 57b48827e33..7c5057c7fb2 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -5,7 +5,7 @@ ERROR HY000: Could not initialize master info structure, check permisions on mas start slave; ERROR HY000: Could not initialize master info structure, check permisions on master.info change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; -Could not initialize master info structure, check permisions on master.info +ERROR HY000: Could not initialize master info structure, check permisions on master.info reset slave; change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; reset master; @@ -81,7 +81,7 @@ a testing temporary tables part 2 show slave status; 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 -127.0.0.1 root MASTER_PORT 60 master-bin.000006 838 slave-relay-bin.000001 8067 master-bin.000004 Yes Yes 0 0 2886 8067 +127.0.0.1 root MASTER_PORT 60 master-bin.000004 2886 slave-relay-bin.000001 7891 master-bin.000004 Yes Yes 0 0 2886 7891 lock tables t3 read; select count(*) from t3 where n >= 4; count(*) diff --git a/mysql-test/r/rpl_user_variables.result b/mysql-test/r/rpl_user_variables.result index 2feef3dd4e3..b715b750b68 100644 --- a/mysql-test/r/rpl_user_variables.result +++ b/mysql-test/r/rpl_user_variables.result @@ -65,11 +65,11 @@ slave-bin.000001 851 User var 2 851 @n1=NULL slave-bin.000001 877 Query 1 877 use `test`; insert into t1 values (@n1) slave-bin.000001 939 Query 1 939 use `test`; insert into t1 values (@n2) slave-bin.000001 1001 Query 1 1001 use `test`; insert into t1 values (@a:=0), (@a:=@a+1), (@a:=@a+1) -slave-bin.000001 1089 User var 2 1089 @a='2' -slave-bin.000001 1124 Query 1 1124 use `test`; insert into t1 values (@a+(@b:=@a+1)) -slave-bin.000001 1196 User var 2 1196 @q='abc' -slave-bin.000001 1233 Query 1 1233 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2')) -slave-bin.000001 1337 User var 2 1337 @a=5 -slave-bin.000001 1379 Query 1 1379 use `test`; insert into t1 values (@a),(@a) +slave-bin.000001 1089 User var 2 1089 @a=2 +slave-bin.000001 1131 Query 1 1131 use `test`; insert into t1 values (@a+(@b:=@a+1)) +slave-bin.000001 1203 User var 2 1203 @q='abc' +slave-bin.000001 1240 Query 1 1240 use `test`; insert t1 values (@q), (@q:=concat(@q, 'n1')), (@q:=concat(@q, 'n2')) +slave-bin.000001 1344 User var 2 1344 @a=5 +slave-bin.000001 1386 Query 1 1386 use `test`; insert into t1 values (@a),(@a) drop table t1; stop slave; diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index e83bbc2fc8c..46888acb73c 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2583,36 +2583,36 @@ explain select t2.companynr,companyname from t4 left join t2 using (companynr) w id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t4 ALL NULL NULL NULL NULL 12 1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists +delete from t2 where fld1=999999; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; companynr companynr 37 36 41 40 -delete from t2 where fld1=999999; -explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; -table type possible_keys key key_len ref rows Extra -t2 ALL NULL NULL NULL NULL 1199 Using where -t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 -explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; -table type possible_keys key key_len ref rows Extra -t2 ALL NULL NULL NULL NULL 1199 Using where -t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 -explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; -table type possible_keys key key_len ref rows Extra -t2 ALL NULL NULL NULL NULL 1199 Using where -t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where -explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; -table type possible_keys key key_len ref rows Extra -t4 ALL NULL NULL NULL NULL 12 -t2 ALL NULL NULL NULL NULL 1199 Using where -explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0; -table type possible_keys key key_len ref rows Extra -t4 ALL PRIMARY NULL NULL NULL 12 -t2 ALL NULL NULL NULL NULL 1199 Using where -explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0; -table type possible_keys key key_len ref rows Extra -t4 ALL NULL NULL NULL NULL 12 -t2 ALL NULL NULL NULL NULL 1199 Using where -plain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; +explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using temporary 1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using where; Using index @@ -3527,11 +3527,11 @@ insert into t2 values (1); insert into t4 values (1,1); explain select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 left join t4 on id3 = id4 where id2 = 1 or id4 = 1; -table type possible_keys key key_len ref rows Extra -t3 system NULL NULL NULL NULL 0 const row not found -t1 ALL NULL NULL NULL NULL 2 -t2 ALL NULL NULL NULL NULL 1 -t4 ALL id4 NULL NULL NULL 1 Using where +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 system NULL NULL NULL NULL 0 const row not found +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 +1 SIMPLE t4 ALL id4 NULL NULL NULL 1 Using where select * from t1 left join t2 on id1 = id2 left join t3 on id1 = id3 left join t4 on id3 = id4 where id2 = 1 or id4 = 1; id1 id2 id3 id4 id44 diff --git a/mysql-test/r/select_safe.result b/mysql-test/r/select_safe.result index dfb12eacd9c..446dd41e216 100644 --- a/mysql-test/r/select_safe.result +++ b/mysql-test/r/select_safe.result @@ -61,21 +61,21 @@ a b 4 a 5 a SELECT @@MAX_SEEKS_FOR_KEY; -@@max_seeks_for_key +@@MAX_SEEKS_FOR_KEY 4294967295 analyze table t1; Table Op Msg_type Msg_text test.t1 analyze status OK insert into t1 values (null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"),(null,"a"); explain select * from t1,t1 as t2 where t1.b=t2.b; -table type possible_keys key key_len ref rows Extra -t1 ALL b NULL NULL NULL 21 -t2 ALL b NULL NULL NULL 16 Using where +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL b NULL NULL NULL 21 +1 SIMPLE t2 ALL b NULL NULL NULL 16 Using where set MAX_SEEKS_FOR_KEY=1; explain select * from t1,t1 as t2 where t1.b=t2.b; -table type possible_keys key key_len ref rows Extra -t1 ALL b NULL NULL NULL 21 -t2 ref b b 21 t1.b 6 Using where +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL b NULL NULL NULL 21 +1 SIMPLE t2 ref b b 21 test.t1.b 6 Using where SET MAX_SEEKS_FOR_KEY=DEFAULT; drop table t1; SET SQL_SAFE_UPDATES=0,SQL_SELECT_LIMIT=DEFAULT, SQL_MAX_JOIN_SIZE=DEFAULT; diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 41fba93db5b..9ee50c3a519 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -6,7 +6,7 @@ explain select (select 2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1247 Select 2 was reduced during optimisation +Note 1248 Select 2 was reduced during optimisation SELECT (SELECT 1) UNION SELECT (SELECT 2); (SELECT 1) 1 @@ -16,8 +16,8 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used 3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1247 Select 2 was reduced during optimisation -Note 1247 Select 4 was reduced during optimisation +Note 1248 Select 2 was reduced during optimisation +Note 1248 Select 4 was reduced during optimisation SELECT (SELECT (SELECT 0 UNION SELECT 0)); (SELECT (SELECT 0 UNION SELECT 0)) 0 @@ -27,7 +27,7 @@ id select_type table type possible_keys key key_len ref rows Extra 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 4 UNION NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1247 Select 2 was reduced during optimisation +Note 1248 Select 2 was reduced during optimisation SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a; ERROR 42S22: Reference 'a' not supported (forward reference in item list) SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b; @@ -608,7 +608,6 @@ x 3 3 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; -ERROR HY000: You can't specify target table 't1' for update in FROM clause INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); ERROR 42S22: Unknown column 'x' in 'field list' INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); @@ -618,6 +617,8 @@ x 2 3 3 +11 +11 2 drop table t1, t2, t3; CREATE TABLE t1 (x int not null, y int, primary key (x)); @@ -667,7 +668,7 @@ EXPLAIN SELECT * FROM t2 WHERE id IN (SELECT 1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ref id id 5 const 1 Using where; Using index Warnings: -Note 1247 Select 2 was reduced during optimisation +Note 1248 Select 2 was reduced during optimisation SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3); id 1 @@ -679,8 +680,8 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ref id id 5 const 1 Using where; Using index 3 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: -Note 1247 Select 3 was reduced during optimisation -Note 1247 Select 2 was reduced during optimisation +Note 1248 Select 3 was reduced during optimisation +Note 1248 Select 2 was reduced during optimisation EXPLAIN SELECT * FROM t2 WHERE id IN (SELECT 1 UNION SELECT 3); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL id 5 NULL 2 Using where; Using index @@ -809,7 +810,7 @@ explain select (select a+1) from t1; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 3 Warnings: -Note 1247 Select 2 was reduced during optimisation +Note 1248 Select 2 was reduced during optimisation select (select a+1) from t1; (select a+1) 2.5 @@ -973,12 +974,12 @@ UNIQUE KEY `maxnumrep` (`maxnumrep`) ) TYPE=MyISAM CHARSET=latin1; INSERT INTO t1 VALUES ('joce','1','','joce'),('test','2','','test'); Warnings: -Warning 1263 Data truncated for column 'date' at row 1 -Warning 1263 Data truncated for column 'date' at row 2 +Warning 1264 Data truncated for column 'date' at row 1 +Warning 1264 Data truncated for column 'date' at row 2 INSERT INTO t2 VALUES ('joce','1','','joce'),('test','2','','test'); Warnings: -Warning 1263 Data truncated for column 'date' at row 1 -Warning 1263 Data truncated for column 'date' at row 2 +Warning 1264 Data truncated for column 'date' at row 1 +Warning 1264 Data truncated for column 'date' at row 2 INSERT INTO t3 VALUES (1,1); SELECT DISTINCT topic FROM t2 WHERE NOT EXISTS(SELECT * FROM t3 WHERE numeropost=topic); @@ -1159,7 +1160,7 @@ insert into t1 values (1,0), (2,0), (3,0); insert into t2 values (1,1), (2,1), (3,1), (2,2); update ignore t1 set b=(select b from t2 where t1.a=t2.a); Warnings: -Error 1240 Subselect returns more than 1 record +Error 1241 Subselect returns more than 1 record select * from t1; a b 1 1 diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 592c787031f..f12be1d363c 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -9,9 +9,9 @@ d mediumtext YES NULL e longtext YES NULL CREATE TABLE t2 (a char(257), b varchar(70000) binary, c varchar(70000000)); Warnings: -Warning 1244 Converting column 'a' from CHAR to TEXT -Warning 1244 Converting column 'b' from CHAR to BLOB -Warning 1244 Converting column 'c' from CHAR to TEXT +Warning 1245 Converting column 'a' from CHAR to TEXT +Warning 1245 Converting column 'b' from CHAR to BLOB +Warning 1245 Converting column 'c' from CHAR to TEXT show columns from t2; Field Type Null Key Default Extra a text YES NULL diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result index b31ef73742d..da25394eb08 100644 --- a/mysql-test/r/type_decimal.result +++ b/mysql-test/r/type_decimal.result @@ -1,4 +1,5 @@ DROP TABLE IF EXISTS t1; +SET SQL_WARNINGS=1; CREATE TABLE t1 ( id int(11) NOT NULL auto_increment, datatype_id int(11) DEFAULT '0' NOT NULL, @@ -157,17 +158,17 @@ insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001"); insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11"); insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1263 Data truncated for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1264 Data truncated for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0"); Warnings: -Warning 1263 Data truncated for column 'a' at row 3 +Warning 1264 Data truncated for column 'a' at row 3 select * from t1; a 0.00 @@ -200,32 +201,32 @@ drop table t1; create table t1 (a decimal(10,2) unsigned); insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 6 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 6 insert into t1 values ("-.1"),("+.1"),(".1"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 1 insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1263 Data truncated for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1264 Data truncated for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0"); Warnings: -Warning 1263 Data truncated for column 'a' at row 3 +Warning 1264 Data truncated for column 'a' at row 3 select * from t1; a 0.00 @@ -258,32 +259,32 @@ drop table t1; create table t1 (a decimal(10,2) zerofill); insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 6 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 6 insert into t1 values ("-.1"),("+.1"),(".1"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 1 insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("1e+1000"),("1e-1000"),("-1e+1000"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1263 Data truncated for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1264 Data truncated for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values ("123.4e"),("123.4e+2"),("123.4e-2"),("123e1"),("123e+0"); Warnings: -Warning 1263 Data truncated for column 'a' at row 3 +Warning 1264 Data truncated for column 'a' at row 3 select * from t1; a 00000000.00 @@ -320,13 +321,13 @@ insert into t1 values (00000000000001),(+0000000000001),(-0000000000001); insert into t1 values (+111111111.11),(111111111.11),(-11111111.11); insert into t1 values (-111111111.11),(+1111111111.11),(1111111111.11); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values (1e+100),(1e-100),(-1e+100); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 3 insert into t1 values (123.4e0),(123.4e+2),(123.4e-2),(123e1),(123e+0); select * from t1; a @@ -360,8 +361,8 @@ drop table t1; create table t1 (a decimal); insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+12345678901'),(99999999999999); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 7 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 7 select * from t1; a -9999999999 @@ -375,9 +376,9 @@ drop table t1; create table t1 (a decimal unsigned); insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 7 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 7 select * from t1; a 0 @@ -391,9 +392,9 @@ drop table t1; create table t1 (a decimal zerofill); insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 7 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 7 select * from t1; a 0000000000 @@ -407,9 +408,9 @@ drop table t1; create table t1 (a decimal unsigned zerofill); insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'a' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 7 +Warning 1263 Data truncated, out of range for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 7 select * from t1; a 0000000000 @@ -423,14 +424,16 @@ drop table t1; create table t1(a decimal(10,0)); insert into t1 values ("1e4294967295"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 +Warning 1264 Data truncated for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 1 select * from t1; a 99999999999 delete from t1; insert into t1 values("1e4294967297"); Warnings: -Warning 1262 Data truncated, out of range for column 'a' at row 1 +Warning 1264 Data truncated for column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'a' at row 1 select * from t1; a 99999999999 diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result index 76f82feb50e..987fa9d5685 100644 --- a/mysql-test/r/type_float.result +++ b/mysql-test/r/type_float.result @@ -15,8 +15,8 @@ f1 float NULL YES NULL select,insert,update,references f2 double NULL YES NULL select,insert,update,references insert into t1 values(10,10),(1e+5,1e+5),(1234567890,1234567890),(1e+10,1e+10),(1e+15,1e+15),(1e+20,1e+20),(1e+50,1e+50),(1e+150,1e+150); Warnings: -Warning 1262 Data truncated, out of range for column 'f1' at row 7 -Warning 1262 Data truncated, out of range for column 'f1' at row 8 +Warning 1263 Data truncated, out of range for column 'f1' at row 7 +Warning 1263 Data truncated, out of range for column 'f1' at row 8 insert into t1 values(-10,-10),(1e-5,1e-5),(1e-10,1e-10),(1e-15,1e-15),(1e-20,1e-20),(1e-50,1e-50),(1e-150,1e-150); select * from t1; f1 f2 diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index 34ae1086e2c..b665f78bbce 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -1,4 +1,5 @@ drop table if exists t1,t2,t3; +SET SQL_WARNINGS=1; CREATE TABLE t1 ( auto int(5) unsigned NOT NULL auto_increment, string char(10) default "hello", @@ -88,33 +89,34 @@ insert into t1 values (NULL,2,2,2,2,2,2,2,2,2,2,2,2,2,NULL,NULL,NULL,NULL,NULL,N insert into t1 values (0,1/3,3,3,3,3,3,3,3,3,3,3,3,3,NULL,'19970303','10:10:10','19970303101010','','','','3',3,3); insert into t1 values (0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,NULL,19970807,080706,19970403090807,-1,-1,-1,'-1',-1,-1); Warnings: -Warning 1262 Data truncated, out of range for column 'utiny' at row 1 -Warning 1262 Data truncated, out of range for column 'ushort' at row 1 -Warning 1262 Data truncated, out of range for column 'umedium' at row 1 -Warning 1262 Data truncated, out of range for column 'ulong' at row 1 -Warning 1263 Data truncated for column 'options' at row 1 -Warning 1263 Data truncated for column 'flags' at row 1 +Warning 1263 Data truncated, out of range for column 'utiny' at row 1 +Warning 1263 Data truncated, out of range for column 'ushort' at row 1 +Warning 1263 Data truncated, out of range for column 'umedium' at row 1 +Warning 1263 Data truncated, out of range for column 'ulong' at row 1 +Warning 1264 Data truncated for column 'options' at row 1 +Warning 1264 Data truncated for column 'flags' at row 1 insert into t1 values (0,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,-4294967295,NULL,0,0,0,-4294967295,-4294967295,-4294967295,'-4294967295',0,"one,two,tree"); Warnings: -Warning 1262 Data truncated, out of range for column 'tiny' at row 1 -Warning 1262 Data truncated, out of range for column 'short' at row 1 -Warning 1262 Data truncated, out of range for column 'medium' at row 1 -Warning 1262 Data truncated, out of range for column 'long_int' at row 1 -Warning 1262 Data truncated, out of range for column 'utiny' at row 1 -Warning 1262 Data truncated, out of range for column 'ushort' at row 1 -Warning 1262 Data truncated, out of range for column 'umedium' at row 1 -Warning 1262 Data truncated, out of range for column 'ulong' at row 1 -Warning 1263 Data truncated for column 'options' at row 1 +Warning 1264 Data truncated for column 'string' at row 1 +Warning 1263 Data truncated, out of range for column 'tiny' at row 1 +Warning 1263 Data truncated, out of range for column 'short' at row 1 +Warning 1263 Data truncated, out of range for column 'medium' at row 1 +Warning 1263 Data truncated, out of range for column 'long_int' at row 1 +Warning 1263 Data truncated, out of range for column 'utiny' at row 1 +Warning 1263 Data truncated, out of range for column 'ushort' at row 1 +Warning 1263 Data truncated, out of range for column 'umedium' at row 1 +Warning 1263 Data truncated, out of range for column 'ulong' at row 1 +Warning 1264 Data truncated for column 'options' at row 1 insert into t1 values (0,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,4294967295,NULL,0,0,0,4294967295,4294967295,4294967295,'4294967295',0,0); Warnings: -Warning 1262 Data truncated, out of range for column 'tiny' at row 1 -Warning 1262 Data truncated, out of range for column 'short' at row 1 -Warning 1262 Data truncated, out of range for column 'medium' at row 1 -Warning 1262 Data truncated, out of range for column 'long_int' at row 1 -Warning 1262 Data truncated, out of range for column 'utiny' at row 1 -Warning 1262 Data truncated, out of range for column 'ushort' at row 1 -Warning 1262 Data truncated, out of range for column 'umedium' at row 1 -Warning 1263 Data truncated for column 'options' at row 1 +Warning 1263 Data truncated, out of range for column 'tiny' at row 1 +Warning 1263 Data truncated, out of range for column 'short' at row 1 +Warning 1263 Data truncated, out of range for column 'medium' at row 1 +Warning 1263 Data truncated, out of range for column 'long_int' at row 1 +Warning 1263 Data truncated, out of range for column 'utiny' at row 1 +Warning 1263 Data truncated, out of range for column 'ushort' at row 1 +Warning 1263 Data truncated, out of range for column 'umedium' at row 1 +Warning 1264 Data truncated for column 'options' at row 1 insert into t1 (tiny) values (1); select auto,string,tiny,short,medium,long_int,longlong,real_float,real_double,utiny,ushort,umedium,ulong,ulonglong,mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000),date_field,time_field,date_time,blob_col,tinyblob_col,mediumblob_col,longblob_col from t1; auto string tiny short medium long_int longlong real_float real_double utiny ushort umedium ulong ulonglong mod(floor(time_stamp/1000000),1000000)-mod(curdate(),1000000) date_field time_field date_time blob_col tinyblob_col mediumblob_col longblob_col @@ -163,12 +165,12 @@ PRIMARY KEY (auto) ); INSERT INTO t2 (string,mediumblob_col,new_field) SELECT string,mediumblob_col,new_field from t1 where auto > 10; Warnings: -Warning 1263 Data truncated for column 'new_field' at row 2 -Warning 1263 Data truncated for column 'new_field' at row 3 -Warning 1263 Data truncated for column 'new_field' at row 4 -Warning 1263 Data truncated for column 'new_field' at row 5 -Warning 1263 Data truncated for column 'new_field' at row 6 -Warning 1263 Data truncated for column 'new_field' at row 7 +Warning 1264 Data truncated for column 'new_field' at row 2 +Warning 1264 Data truncated for column 'new_field' at row 3 +Warning 1264 Data truncated for column 'new_field' at row 4 +Warning 1264 Data truncated for column 'new_field' at row 5 +Warning 1264 Data truncated for column 'new_field' at row 6 +Warning 1264 Data truncated for column 'new_field' at row 7 select * from t2; auto string mediumblob_col new_field 1 2 2 ne @@ -200,9 +202,9 @@ one one drop table t2; create table t2 select * from t1; Warnings: -Warning 1263 Data truncated for column 'options' at row 4 -Warning 1263 Data truncated for column 'options' at row 5 -Warning 1263 Data truncated for column 'options' at row 6 +Warning 1264 Data truncated for column 'options' at row 4 +Warning 1264 Data truncated for column 'options' at row 5 +Warning 1264 Data truncated for column 'options' at row 6 update t2 set string="changed" where auto=16; show full columns from t1; Field Type Collation Null Key Default Extra Privileges Comment diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index 27f2de823c6..5666e865518 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -25,9 +25,9 @@ t 36:30:31 insert into t1 values("10.22.22"),(1234567),(123456789),(123456789.10),("10 22:22"),("12.45a"); Warnings: -Warning 1262 Data truncated, out of range for column 't' at row 2 -Warning 1262 Data truncated, out of range for column 't' at row 3 -Warning 1262 Data truncated, out of range for column 't' at row 4 +Warning 1263 Data truncated, out of range for column 't' at row 2 +Warning 1263 Data truncated, out of range for column 't' at row 3 +Warning 1263 Data truncated, out of range for column 't' at row 4 select * from t1; t 10:22:33 diff --git a/mysql-test/r/type_uint.result b/mysql-test/r/type_uint.result index ee81295e696..d948ca47972 100644 --- a/mysql-test/r/type_uint.result +++ b/mysql-test/r/type_uint.result @@ -1,9 +1,10 @@ drop table if exists t1; +SET SQL_WARNINGS=1; create table t1 (this int unsigned); insert into t1 values (1); insert into t1 values (-1); Warnings: -Warning 1262 Data truncated, out of range for column 'this' at row 1 +Warning 1263 Data truncated, out of range for column 'this' at row 1 select * from t1; this 1 diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index c29859bd4d4..396eba7197b 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -90,6 +90,13 @@ explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a l id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 4 2 UNION t2 ALL NULL NULL NULL NULL 4 Using filesort +(select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2; +a b +1 a +2 b +select found_rows(); +found_rows() +6 select sql_calc_found_rows a,b from t1 union all select a,b from t2 limit 2; a b 1 a @@ -358,7 +365,7 @@ explain (select * from t1 where a=1 and b=10) union (select t1.a,t2.a from t1,t2 id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 UNION t1 index PRIMARY PRIMARY 4 NULL 4 Using index -2 UNION t2 index PRIMARY PRIMARY 4 NULL 4 Using where; Using index +2 UNION t2 index PRIMARY PRIMARY 4 NULL 3 Using where; Using index explain (select * from t1 where a=1) union (select * from t1 where b=1); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 const PRIMARY PRIMARY 4 const 1 diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 0ad165a861a..9d4710ff729 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -2,23 +2,24 @@ drop table if exists t1, t2; Warnings: Note 1051 Unknown table 't1' Note 1051 Unknown table 't2' +SET SQL_WARNINGS=1; create table t1 (a int); insert into t1 values (1); insert into t1 values ("hej"); Warnings: -Warning 1263 Data truncated for column 'a' at row 1 +Warning 1264 Data truncated for column 'a' at row 1 insert into t1 values ("hej"),("då"); Warnings: -Warning 1263 Data truncated for column 'a' at row 1 -Warning 1263 Data truncated for column 'a' at row 2 +Warning 1264 Data truncated for column 'a' at row 1 +Warning 1264 Data truncated for column 'a' at row 2 set SQL_WARNINGS=1; insert into t1 values ("hej"); Warnings: -Warning 1263 Data truncated for column 'a' at row 1 +Warning 1264 Data truncated for column 'a' at row 1 insert into t1 values ("hej"),("då"); Warnings: -Warning 1263 Data truncated for column 'a' at row 1 -Warning 1263 Data truncated for column 'a' at row 2 +Warning 1264 Data truncated for column 'a' at row 1 +Warning 1264 Data truncated for column 'a' at row 2 drop table t1; set SQL_WARNINGS=0; drop temporary table if exists not_exists; @@ -45,13 +46,13 @@ drop table t1; create table t1(a tinyint, b int not null, c date, d char(5)); load data infile '../../std_data/warnings_loaddata.dat' into table t1 fields terminated by ','; Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'b' at row 2 -Warning 1263 Data truncated for column 'd' at row 3 -Warning 1263 Data truncated for column 'c' at row 4 -Warning 1259 Record count is fewer than the column count at row 5 -Warning 1263 Data truncated for column 'b' at row 6 -Warning 1260 Record count is more than the column count at row 7 -Warning 1262 Data truncated, out of range for column 'a' at row 8 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'b' at row 2 +Warning 1264 Data truncated for column 'd' at row 3 +Warning 1264 Data truncated for column 'c' at row 4 +Warning 1260 Record count is fewer than the column count at row 5 +Warning 1264 Data truncated for column 'b' at row 6 +Warning 1261 Record count is more than the column count at row 7 +Warning 1263 Data truncated, out of range for column 'a' at row 8 select @@warning_count; @@warning_count 7 @@ -59,42 +60,42 @@ drop table t1; create table t1(a tinyint NOT NULL, b tinyint unsigned, c char(5)); insert into t1 values(NULL,100,'mysql'),(10,-1,'mysql ab'),(500,256,'open source'),(20,NULL,'test'); Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'a' at row 1 -Warning 1262 Data truncated, out of range for column 'b' at row 2 -Warning 1263 Data truncated for column 'c' at row 2 -Warning 1262 Data truncated, out of range for column 'a' at row 3 -Warning 1262 Data truncated, out of range for column 'b' at row 3 -Warning 1263 Data truncated for column 'c' at row 3 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 1 +Warning 1263 Data truncated, out of range for column 'b' at row 2 +Warning 1264 Data truncated for column 'c' at row 2 +Warning 1263 Data truncated, out of range for column 'a' at row 3 +Warning 1263 Data truncated, out of range for column 'b' at row 3 +Warning 1264 Data truncated for column 'c' at row 3 alter table t1 modify c char(4); Warnings: -Warning 1263 Data truncated for column 'c' at row 1 -Warning 1263 Data truncated for column 'c' at row 2 +Warning 1264 Data truncated for column 'c' at row 1 +Warning 1264 Data truncated for column 'c' at row 2 alter table t1 add d char(2); update t1 set a=NULL where a=10; Warnings: -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'a' at row 2 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 2 update t1 set c='mysql ab' where c='test'; Warnings: -Warning 1263 Data truncated for column 'c' at row 4 +Warning 1264 Data truncated for column 'c' at row 4 update t1 set d=c; Warnings: -Warning 1263 Data truncated for column 'd' at row 1 -Warning 1263 Data truncated for column 'd' at row 2 -Warning 1263 Data truncated for column 'd' at row 3 -Warning 1263 Data truncated for column 'd' at row 4 +Warning 1264 Data truncated for column 'd' at row 1 +Warning 1264 Data truncated for column 'd' at row 2 +Warning 1264 Data truncated for column 'd' at row 3 +Warning 1264 Data truncated for column 'd' at row 4 create table t2(a tinyint NOT NULL, b char(3)); insert into t2 select b,c from t1; Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warning 1263 Data truncated for column 'b' at row 2 -Warning 1263 Data truncated for column 'b' at row 3 -Warning 1261 Data truncated, NULL supplied to NOT NULL column 'a' at row 4 -Warning 1263 Data truncated for column 'b' at row 4 +Warning 1264 Data truncated for column 'b' at row 1 +Warning 1264 Data truncated for column 'b' at row 2 +Warning 1264 Data truncated for column 'b' at row 3 +Warning 1262 Data truncated, NULL supplied to NOT NULL column 'a' at row 4 +Warning 1264 Data truncated for column 'b' at row 4 insert into t2(b) values('mysqlab'); set sql_warnings=1; insert into t2(b) values('mysqlab'); Warnings: -Warning 1263 Data truncated for column 'b' at row 1 +Warning 1264 Data truncated for column 'b' at row 1 set sql_warnings=0; drop table t1, t2; create table t1(a char(10)); @@ -102,24 +103,24 @@ alter table t1 add b char; set max_error_count=10; update t1 set b=a; Warnings: -Warning 1263 Data truncated for column 'b' at row 1 -Warning 1263 Data truncated for column 'b' at row 2 -Warning 1263 Data truncated for column 'b' at row 3 -Warning 1263 Data truncated for column 'b' at row 4 -Warning 1263 Data truncated for column 'b' at row 5 -Warning 1263 Data truncated for column 'b' at row 6 -Warning 1263 Data truncated for column 'b' at row 7 -Warning 1263 Data truncated for column 'b' at row 8 -Warning 1263 Data truncated for column 'b' at row 9 -Warning 1263 Data truncated for column 'b' at row 10 +Warning 1264 Data truncated for column 'b' at row 1 +Warning 1264 Data truncated for column 'b' at row 2 +Warning 1264 Data truncated for column 'b' at row 3 +Warning 1264 Data truncated for column 'b' at row 4 +Warning 1264 Data truncated for column 'b' at row 5 +Warning 1264 Data truncated for column 'b' at row 6 +Warning 1264 Data truncated for column 'b' at row 7 +Warning 1264 Data truncated for column 'b' at row 8 +Warning 1264 Data truncated for column 'b' at row 9 +Warning 1264 Data truncated for column 'b' at row 10 select @@warning_count; @@warning_count 50 drop table t1; create table t1 (id int) type=isam; Warnings: -Warning 1264 Using storage engine MYISAM for table 't1' +Warning 1265 Using storage engine MYISAM for table 't1' alter table t1 type=isam; Warnings: -Warning 1264 Using storage engine MYISAM for table 't1' +Warning 1265 Using storage engine MYISAM for table 't1' drop table t1; diff --git a/mysql-test/t/auto_increment.test b/mysql-test/t/auto_increment.test index b46993ec6dd..a036121f297 100644 --- a/mysql-test/t/auto_increment.test +++ b/mysql-test/t/auto_increment.test @@ -4,6 +4,7 @@ --disable_warnings drop table if exists t1; --enable_warnings +SET SQL_WARNINGS=1; create table t1 (a int not null auto_increment,b int, primary key (a)) type=myisam auto_increment=3; insert into t1 values (1,1),(NULL,3),(NULL,4); diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test index 8aa17061174..4d4ceb062e4 100644 --- a/mysql-test/t/case.test +++ b/mysql-test/t/case.test @@ -60,14 +60,14 @@ CREATE TABLE t1 SELECT SHOW CREATE TABLE t1; DROP TABLE t1; ---error 1265 +--error 1266 SELECT CASE WHEN 1 THEN _latin1'a' COLLATE latin1_danish_ci ELSE _latin1'a' COLLATE latin1_swedish_ci END; ---error 1268 +--error 1269 SELECT CASE _latin1'a' COLLATE latin1_general_ci WHEN _latin1'a' COLLATE latin1_danish_ci THEN 1 WHEN _latin1'a' COLLATE latin1_swedish_ci THEN 2 @@ -90,9 +90,9 @@ CASE _latin1'a' WHEN _latin1'A' COLLATE latin1_bin THEN '1' ELSE 2 END # # Check COALESCE argument types aggregation ---error 1265 +--error 1266 CREATE TABLE t1 SELECT COALESCE(_latin1'a',_latin2'a'); ---error 1265 +--error 1266 CREATE TABLE t1 SELECT COALESCE('a' COLLATE latin1_swedish_ci,'b' COLLATE latin1_bin); CREATE TABLE t1 SELECT COALESCE(1), COALESCE(1.0),COALESCE('a'), diff --git a/mysql-test/t/convert.test b/mysql-test/t/convert.test deleted file mode 100644 index f26ef3a8c72..00000000000 --- a/mysql-test/t/convert.test +++ /dev/null @@ -1,11 +0,0 @@ -# Test of character set conversions - -# Test that SET DEFAULT works - -select @@convert_character_set; -select @@global.convert_character_set; -show variables like "%convert_character_set%"; -SET CHARACTER SET cp1251_koi8; -select @@convert_character_set; -SET CHARACTER SET DEFAULT; -select @@convert_character_set; diff --git a/mysql-test/t/ctype_collate.test b/mysql-test/t/ctype_collate.test index 23039a4b116..d42696e693b 100644 --- a/mysql-test/t/ctype_collate.test +++ b/mysql-test/t/ctype_collate.test @@ -7,12 +7,12 @@ CREATE TABLE t1 ( latin1_f CHAR(32) CHARACTER SET latin1 NOT NULL ); ---error 1251 +--error 1252 CREATE TABLE t2 ( latin1_f CHAR(32) CHARACTER SET latin1 COLLATE koi8r_general_ci NOT NULL ); ---error 1271 +--error 1272 CREATE TABLE t2 ( latin1_f CHAR(32) CHARACTER SET latin1 COLLATE some_non_existing_col NOT NULL ); @@ -66,7 +66,7 @@ SELECT latin1_f FROM t1 ORDER BY latin1_f COLLATE latin1_swedish_ci; SELECT latin1_f FROM t1 ORDER BY latin1_f COLLATE latin1_german2_ci; SELECT latin1_f FROM t1 ORDER BY latin1_f COLLATE latin1_general_ci; SELECT latin1_f FROM t1 ORDER BY latin1_f COLLATE latin1_bin; ---error 1251 +--error 1252 SELECT latin1_f FROM t1 ORDER BY latin1_f COLLATE koi8r_general_ci; --SELECT latin1_f COLLATE koi8r FROM t1 ; @@ -76,7 +76,7 @@ SELECT latin1_f COLLATE latin1_swedish_ci AS latin1_f_as FROM t1 ORDER BY latin1 SELECT latin1_f COLLATE latin1_german2_ci AS latin1_f_as FROM t1 ORDER BY latin1_f_as; SELECT latin1_f COLLATE latin1_general_ci AS latin1_f_as FROM t1 ORDER BY latin1_f_as; SELECT latin1_f COLLATE latin1_bin AS latin1_f_as FROM t1 ORDER BY latin1_f_as; ---error 1251 +--error 1252 SELECT latin1_f COLLATE koi8r_general_ci AS latin1_f_as FROM t1 ORDER BY latin1_f_as; @@ -87,7 +87,7 @@ SELECT latin1_f,count(*) FROM t1 GROUP BY latin1_f COLLATE latin1_swedish_ci; SELECT latin1_f,count(*) FROM t1 GROUP BY latin1_f COLLATE latin1_german2_ci; SELECT latin1_f,count(*) FROM t1 GROUP BY latin1_f COLLATE latin1_general_ci; SELECT latin1_f,count(*) FROM t1 GROUP BY latin1_f COLLATE latin1_bin; ---error 1251 +--error 1252 SELECT latin1_f,count(*) FROM t1 GROUP BY latin1_f COLLATE koi8r_general_ci; @@ -98,7 +98,7 @@ SELECT DISTINCT latin1_f COLLATE latin1_swedish_ci FROM t1; SELECT DISTINCT latin1_f COLLATE latin1_german2_ci FROM t1; SELECT DISTINCT latin1_f COLLATE latin1_general_ci FROM t1; SELECT DISTINCT latin1_f COLLATE latin1_bin FROM t1; ---error 1271 +--error 1272 SELECT DISTINCT latin1_f COLLATE koi8r FROM t1; @@ -152,7 +152,6 @@ DROP TABLE t1; CREATE TABLE t1 (s1 CHAR(5) COLLATE latin1_german1_ci, s2 CHAR(5) COLLATE latin1_swedish_ci); ---error 1265 +--error 1266 SELECT * FROM t1 WHERE s1 = s2; DROP TABLE t1; - \ No newline at end of file diff --git a/mysql-test/t/ctype_latin1_de.test b/mysql-test/t/ctype_latin1_de.test index afad89729b4..52ee227b011 100644 --- a/mysql-test/t/ctype_latin1_de.test +++ b/mysql-test/t/ctype_latin1_de.test @@ -1,9 +1,13 @@ # # Test latin_de character set # + +select @@collation_connection; + --disable_warnings drop table if exists t1; --enable_warnings + create table t1 (a char (20) not null, b int not null auto_increment, index (a,b)); insert into t1 (a) values ('ä'),('ac'),('ae'),('ad'),('Äc'),('aeb'); insert into t1 (a) values ('üc'),('uc'),('ue'),('ud'),('Ü'),('ueb'),('uf'); diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test index e624ded0102..a55cbb45fd9 100644 --- a/mysql-test/t/drop.test +++ b/mysql-test/t/drop.test @@ -1,6 +1,7 @@ # Initialise --disable_warnings drop table if exists t1; +drop database if exists mysqltest; --enable_warnings --error 1051; @@ -17,7 +18,6 @@ select * from t1; # now test for a bug in drop database - it is important that the name # of the table is the same as the name of the database - in the original # code this triggered a bug -drop database if exists mysqltest; create database mysqltest; drop database if exists mysqltest; create database mysqltest; diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test index 105612bf238..689b061f88d 100644 --- a/mysql-test/t/func_in.test +++ b/mysql-test/t/func_in.test @@ -61,11 +61,11 @@ c char(1) character set latin1 collate latin1_danish_ci ); insert into t1 values ('A','B','C'); insert into t1 values ('a','c','c'); ---error 1265 +--error 1266 select * from t1 where a in (b); ---error 1268 -select * from t1 where a in (b,c); --error 1269 +select * from t1 where a in (b,c); +--error 1270 select * from t1 where 'a' in (a,b,c); select * from t1 where 'a' in (a); select * from t1 where a in ('a'); diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test index e462e0a96c3..b152c94096c 100644 --- a/mysql-test/t/func_set.test +++ b/mysql-test/t/func_set.test @@ -15,6 +15,7 @@ select export_set(9,"Y","N","-",5),export_set(9,"Y","N"),export_set(9,"Y","N","" select elt(2,1),field(NULL,"a","b","c"); select find_in_set("","a,b,c"),find_in_set("","a,b,c,"),find_in_set("",",a,b,c"); select find_in_set("abc","abc"),find_in_set("ab","abc"),find_in_set("abcd","abc"); +select interval(null, 1, 10, 100); # # test for a bug with elt() @@ -33,4 +34,3 @@ insert into t2 values (1,1),(2,1),(3,1),(4,2); select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id; select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id; drop table t1,t2; -select interval(null, 1, 10, 100); diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index 14267976104..b421f47e5b8 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -143,20 +143,20 @@ select 1=_latin1'1'; select _latin1'1'=1; select _latin2'1'=1; select 1=_latin2'1'; ---error 1265 +--error 1266 select _latin1'1'=_latin2'1'; select row('a','b','c') = row('a','b','c'); select row('A','b','c') = row('a','b','c'); select row('A' COLLATE latin1_bin,'b','c') = row('a','b','c'); select row('A','b','c') = row('a' COLLATE latin1_bin,'b','c'); ---error 1265 +--error 1266 select row('A' COLLATE latin1_general_ci,'b','c') = row('a' COLLATE latin1_bin,'b','c'); ---error 1265 +--error 1266 select concat(_latin1'a',_latin2'a'); ---error 1268 -select concat(_latin1'a',_latin2'a',_latin5'a'); --error 1269 +select concat(_latin1'a',_latin2'a',_latin5'a'); +--error 1270 select concat(_latin1'a',_latin2'a',_latin5'a',_latin7'a'); @@ -167,9 +167,9 @@ select FIELD('b','A','B'); select FIELD('B','A','B'); select FIELD('b' COLLATE latin1_bin,'A','B'); select FIELD('b','A' COLLATE latin1_bin,'B'); ---error 1268 +--error 1269 select FIELD(_latin2'b','A','B'); ---error 1268 +--error 1269 select FIELD('b',_latin2'A','B'); select FIELD('b',_latin2'A','B',1); @@ -177,55 +177,55 @@ select FIELD('b',_latin2'A','B',1); select POSITION(_latin1'B' IN _latin1'abcd'); select POSITION(_latin1'B' IN _latin1'abcd' COLLATE latin1_bin); select POSITION(_latin1'B' COLLATE latin1_bin IN _latin1'abcd'); ---error 1265 +--error 1266 select POSITION(_latin1'B' COLLATE latin1_general_ci IN _latin1'abcd' COLLATE latin1_bin); ---error 1265 +--error 1266 select POSITION(_latin1'B' IN _latin2'abcd'); select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d'); --fix this: --select FIND_IN_SET(_latin1'B',_latin1'a,b,c,d' COLLATE latin1_bin); --select FIND_IN_SET(_latin1'B' COLLATE latin1_bin,_latin1'a,b,c,d'); ---error 1265 +--error 1266 select FIND_IN_SET(_latin1'B' COLLATE latin1_general_ci,_latin1'a,b,c,d' COLLATE latin1_bin); ---error 1265 +--error 1266 select FIND_IN_SET(_latin1'B',_latin2'a,b,c,d'); select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd',2); --fix this: --select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_bin,_latin1'd',2); --select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin1'd' COLLATE latin1_bin,2); ---error 1265 +--error 1266 select SUBSTRING_INDEX(_latin1'abcdabcdabcd',_latin2'd',2); ---error 1265 +--error 1266 select SUBSTRING_INDEX(_latin1'abcdabcdabcd' COLLATE latin1_general_ci,_latin1'd' COLLATE latin1_bin,2); select _latin1'B' between _latin1'a' and _latin1'c'; select _latin1'B' collate latin1_bin between _latin1'a' and _latin1'c'; select _latin1'B' between _latin1'a' collate latin1_bin and _latin1'c'; select _latin1'B' between _latin1'a' and _latin1'c' collate latin1_bin; ---error 1268 +--error 1269 select _latin2'B' between _latin1'a' and _latin1'b'; ---error 1268 +--error 1269 select _latin1'B' between _latin2'a' and _latin1'b'; ---error 1268 +--error 1269 select _latin1'B' between _latin1'a' and _latin2'b'; ---error 1268 +--error 1269 select _latin1'B' collate latin1_general_ci between _latin1'a' collate latin1_bin and _latin1'b'; select _latin1'B' in (_latin1'a',_latin1'b'); select _latin1'B' collate latin1_bin in (_latin1'a',_latin1'b'); select _latin1'B' in (_latin1'a' collate latin1_bin,_latin1'b'); select _latin1'B' in (_latin1'a',_latin1'b' collate latin1_bin); ---error 1268 +--error 1269 select _latin2'B' in (_latin1'a',_latin1'b'); ---error 1268 +--error 1269 select _latin1'B' in (_latin2'a',_latin1'b'); ---error 1268 +--error 1269 select _latin1'B' in (_latin1'a',_latin2'b'); ---error 1268 +--error 1269 select _latin1'B' COLLATE latin1_general_ci in (_latin1'a' COLLATE latin1_bin,_latin1'b'); ---error 1268 +--error 1269 select _latin1'B' COLLATE latin1_general_ci in (_latin1'a',_latin1'b' COLLATE latin1_bin); select collation(bin(130)), coercibility(bin(130)); @@ -311,7 +311,7 @@ select SUBSTR('abcdefg',1,-1) FROM DUAL; # when an error on a lower level (in concat) has accured: # create table t7 (s1 char); ---error 1265 +--error 1266 select * from t7 where concat(s1 collate latin1_general_ci,s1 collate latin1_swedish_ci) = 'AA'; drop table t7; diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test index 4f44ec8fef1..ae1963dd3f5 100644 --- a/mysql-test/t/func_test.test +++ b/mysql-test/t/func_test.test @@ -25,6 +25,14 @@ insert t1 values (1); select * from t1 where 1 xor 1; drop table t1; +# +# Wrong usage of functions +# + +select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1; +select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1; +select 1 and 0 or 2, 2 or 1 and 0; + # # Coercibility # @@ -33,9 +41,9 @@ select _koi8r'a' = _koi8r'A' COLLATE koi8r_general_ci; select _koi8r'a' = _koi8r'A' COLLATE koi8r_bin; select _koi8r'a' COLLATE koi8r_general_ci = _koi8r'A'; select _koi8r'a' COLLATE koi8r_bin = _koi8r'A'; ---error 1265 +--error 1266 select _koi8r'a' COLLATE koi8r_bin = _koi8r'A' COLLATE koi8r_general_ci; ---error 1265 +--error 1266 select _koi8r'a' = _latin1'A'; select strcmp(_koi8r'a', _koi8r'A'); @@ -43,9 +51,9 @@ select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_general_ci); select strcmp(_koi8r'a', _koi8r'A' COLLATE koi8r_bin); select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A'); select strcmp(_koi8r'a' COLLATE koi8r_bin, _koi8r'A'); ---error 1265 +--error 1266 select strcmp(_koi8r'a' COLLATE koi8r_general_ci, _koi8r'A' COLLATE koi8r_bin); ---error 1265 +--error 1266 select strcmp(_koi8r'a', _latin1'A'); select _koi8r'a' LIKE _koi8r'A'; @@ -53,17 +61,7 @@ select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_general_ci; select _koi8r'a' LIKE _koi8r'A' COLLATE koi8r_bin; select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A'; select _koi8r'a' COLLATE koi8r_bin LIKE _koi8r'A'; ---error 1265 +--error 1266 select _koi8r'a' COLLATE koi8r_general_ci LIKE _koi8r'A' COLLATE koi8r_bin; ---error 1265 +--error 1266 select _koi8r'a' LIKE _latin1'A'; - - - -# -# Wrong usage of functions -# - -select 5 between 0 and 10 between 0 and 1,(5 between 0 and 10) between 0 and 1; -select 1 and 2 between 2 and 10, 2 between 2 and 10 and 1; -select 1 and 0 or 2, 2 or 1 and 0; diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index b1338b790fd..f48ada33866 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1,9 +1,10 @@ +# Test of GRANT commands + +# Cleanup --disable_warnings drop table if exists t1; --enable_warnings -create table t1 (a int); - # # Test that SSL options works properly # @@ -74,13 +75,19 @@ delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1'; flush privileges; drop table t1; + +# +# Test some error conditions +# --error 1221 GRANT FILE on mysqltest.* to mysqltest_1@localhost; +select 1; -- To test that the previous command didn't cause problems # # Test for 'drop user', 'revoke privileges, grant' # +create table t1 (a int); grant ALL PRIVILEGES on *.* to drop_user2@localhost with GRANT OPTION; show grants for drop_user2@localhost; revoke all privileges, grant from drop_user2@localhost; @@ -93,19 +100,18 @@ show grants for drop_user@localhost; revoke all privileges, grant from drop_user@localhost; show grants for drop_user@localhost; drop user drop_user@localhost; ---error 1267 +--error 1268 revoke all privileges, grant from drop_user@localhost; grant select(a) on test.t1 to drop_user1@localhost; grant select on test.t1 to drop_user2@localhost; grant select on test.* to drop_user3@localhost; grant select on *.* to drop_user4@localhost; ---error 1266 +--error 1267 drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; revoke all privileges, grant from drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; - drop table t1; diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test index d99c7a87f88..1153622a40f 100644 --- a/mysql-test/t/group_by.test +++ b/mysql-test/t/group_by.test @@ -132,7 +132,7 @@ CREATE TABLE t1 ( assigned_to mediumint(9) DEFAULT '0' NOT NULL, bug_file_loc text, bug_severity enum('blocker','critical','major','normal','minor','trivial','enhancement') DEFAULT 'blocker' NOT NULL, - bug_status enum('NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED') DEFAULT 'NEW' NOT NULL, + bug_status enum('','NEW','ASSIGNED','REOPENED','RESOLVED','VERIFIED','CLOSED') DEFAULT 'NEW' NOT NULL, creation_ts datetime DEFAULT '0000-00-00 00:00:00' NOT NULL, delta_ts timestamp(14), short_desc mediumtext, diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index 09dd06c817c..99ca858990c 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -86,9 +86,8 @@ handler t2 read first; drop table t1; # -# test case for the bug #787 +# Test case for the bug #787 # - create table t1 (a int); insert into t1 values (1),(2),(3),(4),(5),(6); delete from t1 limit 2; @@ -101,7 +100,7 @@ handler t1 read first; drop table t1; # -#test for #751 +# Test for #751 # create table t1(a int, index(a)); insert into t1 values (1), (2), (3); @@ -111,4 +110,3 @@ handler t1 read a=(W); --error 1210 handler t1 read a=(a); drop table t1; - diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test index c708ea2baf6..797472e7769 100644 --- a/mysql-test/t/heap.test +++ b/mysql-test/t/heap.test @@ -105,7 +105,7 @@ insert into t1 values ("hello"),("hello"),("hello"),("hello"),("hello"),("a"),(" explain select * from t1 where btn like "q%"; select * from t1 where btn like "q%"; alter table t1 add column new_col char(1) not null, add key (btn,new_col), drop key btn; -update t1 set new_col=btn; +update t1 set new_col=left(btn,1); explain select * from t1 where btn="a"; explain select * from t1 where btn="a" and new_col="a"; drop table t1; diff --git a/mysql-test/t/heap_btree.test b/mysql-test/t/heap_btree.test index 80a7753d4b1..34aeeec0a11 100644 --- a/mysql-test/t/heap_btree.test +++ b/mysql-test/t/heap_btree.test @@ -113,7 +113,7 @@ insert into t1 values ("hello"),("hello"),("hello"),("hello"),("hello"),("a"),(" explain select * from t1 where btn like "q%"; select * from t1 where btn like "q%"; alter table t1 add column new_col char(1) not null, add key using BTREE (btn,new_col), drop key btn; -update t1 set new_col=btn; +update t1 set new_col=left(btn,1); explain select * from t1 where btn="a"; explain select * from t1 where btn="a" and new_col="a"; drop table t1; diff --git a/mysql-test/t/heap_hash.test b/mysql-test/t/heap_hash.test index 7b375fdfa3c..f339a10efc6 100644 --- a/mysql-test/t/heap_hash.test +++ b/mysql-test/t/heap_hash.test @@ -105,7 +105,7 @@ insert into t1 values ("hello"),("hello"),("hello"),("hello"),("hello"),("a"),(" explain select * from t1 where btn like "q%"; select * from t1 where btn like "q%"; alter table t1 add column new_col char(1) not null, add key using HASH (btn,new_col), drop key btn; -update t1 set new_col=btn; +update t1 set new_col=left(btn,1); explain select * from t1 where btn="a"; explain select * from t1 where btn="a" and new_col="a"; drop table t1; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 5ca357efe90..6e7eb0ea06f 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -489,8 +489,8 @@ DROP TABLE t1; # # Test prefix key # ---error 1089 create table t1 (a char(20), unique (a(5))) type=innodb; +drop table t1; create table t1 (a char(20), index (a(5))) type=innodb; show create table t1; drop table t1; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index 4ac5a69a508..556b1ac9c8f 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -87,7 +87,6 @@ let $VERSION=`select version()`; --replace_result $VERSION VERSION show binlog events; drop table t1, t2; -drop table if exists t1, t2; # # Test of insert ... select from same table diff --git a/mysql-test/t/key.test b/mysql-test/t/key.test index de97c639812..3b4cd7358cc 100644 --- a/mysql-test/t/key.test +++ b/mysql-test/t/key.test @@ -1,10 +1,11 @@ -# -# This failed for Elizabeth Mattijsen -# - --disable_warnings drop table if exists t1,t2,t3; --enable_warnings +SET SQL_WARNINGS=1; + +# +# This failed for Elizabeth Mattijsen +# CREATE TABLE t1 ( ID CHAR(32) NOT NULL, diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test index 2da18b68624..fb6b6b0027f 100644 --- a/mysql-test/t/key_cache.test +++ b/mysql-test/t/key_cache.test @@ -38,5 +38,5 @@ SET @@global.key_buffer_size=@save_key_buffer; --error 1064 SELECT @@default.key_buffer_size; ---error 1270 +--error 1271 SELECT @@skr.table_type="test"; diff --git a/mysql-test/t/lock_tables_lost_commit-master.opt b/mysql-test/t/lock_tables_lost_commit-master.opt index d357a51cb27..51ccb915ef0 100644 --- a/mysql-test/t/lock_tables_lost_commit-master.opt +++ b/mysql-test/t/lock_tables_lost_commit-master.opt @@ -1 +1 @@ ---binlog-ignore-db=test innodb \ No newline at end of file +--binlog-ignore-db=test diff --git a/mysql-test/t/lock_tables_lost_commit.test b/mysql-test/t/lock_tables_lost_commit.test index a12ee7369cb..a8a7a65bd76 100644 --- a/mysql-test/t/lock_tables_lost_commit.test +++ b/mysql-test/t/lock_tables_lost_commit.test @@ -4,7 +4,9 @@ connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; +--disable_warnings drop table if exists t1; +--enable_warnings create table t1(a int) type=innodb; lock tables t1 write; insert into t1 values(10); diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index 80d46d1ef0c..5267b57259b 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -6,6 +6,7 @@ --disable_warnings drop table if exists t1,t2; --enable_warnings +SET SQL_WARNINGS=1; # # Test problem with CHECK TABLE; @@ -33,11 +34,13 @@ create table t1 (a tinyint not null auto_increment, b blob not null, primary key let $1=100; disable_query_log; +SET SQL_WARNINGS=0; while ($1) { eval insert into t1 (b) values(repeat(char(65+$1),65550-$1)); dec $1; } +SET SQL_WARNINGS=1; enable_query_log; check table t1; repair table t1; diff --git a/mysql-test/t/row.test b/mysql-test/t/row.test index fb5fff86b11..252830cfc98 100644 --- a/mysql-test/t/row.test +++ b/mysql-test/t/row.test @@ -15,7 +15,7 @@ select row('b',1.5,3) IN (row(3,NULL,3), row('a',1.5,3), row(1,3,3)); select row('b',1.5,3) IN (row('b',NULL,3), row('a',1.5,3), row(1,3,3)); select row('b',1.5,3) IN (row('b',NULL,4), row('a',1.5,3), row(1,3,3)); select (1,2,(3,4)) IN ((3,2,(3,4)), (1,2,(3,4))); --- error 1239 +-- error 1240 select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,4)); select row(1,2,row(3,4)) IN (row(3,2,row(3,4)), row(1,2,row(3,NULL))); @@ -36,12 +36,12 @@ SELECT ROW(NULL,2,3)=ROW(NULL,2,3); SELECT ROW(NULL,2,3)<=>ROW(NULL,2,3); SELECT ROW(1,2,ROW(3,4,5))=ROW(1,2,ROW(3,4,5)); SELECT ROW('test',2,3.33)=ROW('test',2,3.33); --- error 1239 +-- error 1240 SELECT ROW('test',2,3.33)=ROW('test',2,3.33,4); SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,33)); SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,3)); SELECT ROW('test',2,ROW(3,33))=ROW('test',2,ROW(3,NULL)); --- error 1239 +-- error 1240 SELECT ROW('test',2,ROW(3,33))=ROW('test',2,4); create table t1 ( a int, b int, c int); @@ -55,15 +55,15 @@ select ROW(a,b,c) IN(row(1,2,3), row(3,2,1)) from t1; select ROW(1,2,3) IN(row(a,b,c), row(1,2,3)) from t1; drop table t1; --- error 1239 +-- error 1240 select ROW(1,1); create table t1 (i int); --- error 1239 +-- error 1240 select 1 from t1 where ROW(1,1); --- error 1239 +-- error 1240 select count(*) from t1 order by ROW(1,1); --- error 1239 +-- error 1240 select count(*) from t1 having (1,1) order by i; drop table t1; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 1d7da94d455..a23db3584de 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -9,12 +9,12 @@ SELECT (SELECT 1) UNION SELECT (SELECT 2); explain SELECT (SELECT 1) UNION SELECT (SELECT 2); SELECT (SELECT (SELECT 0 UNION SELECT 0)); explain SELECT (SELECT (SELECT 0 UNION SELECT 0)); --- error 1245 +-- error 1246 SELECT (SELECT 1 FROM (SELECT 1) as b HAVING a=1) as a; --- error 1245 +-- error 1246 SELECT (SELECT 1 FROM (SELECT 1) as b HAVING b=1) as a,(SELECT 1 FROM (SELECT 1) as c HAVING a=1) as b; SELECT (SELECT 1),MAX(1) FROM (SELECT 1) as a; --- error 1245 +-- error 1246 SELECT (SELECT a) as a; EXPLAIN SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1; SELECT 1 FROM (SELECT 1 as a) as b HAVING (SELECT a)=1; @@ -24,7 +24,7 @@ SELECT 1 as a FROM (SELECT 1) as b HAVING (SELECT a)=1; -- error 1054 SELECT 1 FROM (SELECT (SELECT a) b) c; SELECT * FROM (SELECT 1 as id) b WHERE id IN (SELECT * FROM (SELECT 1 as id) c ORDER BY id); --- error 1239 +-- error 1240 SELECT * FROM (SELECT 1) a WHERE 1 IN (SELECT 1,1); SELECT 1 IN (SELECT 1); SELECT 1 FROM (SELECT 1 as a) b WHERE 1 IN (SELECT (SELECT a)); @@ -51,7 +51,7 @@ SELECT (SELECT 'b',2,'a') = ROW(1.5,2,'a'); SELECT (SELECT 1.5,2,'a') = ROW(1.5,'c','a'); SELECT (SELECT 1.5,'c','a') = ROW(1.5,2,'a'); --- error 1239 +-- error 1240 SELECT (SELECT * FROM (SELECT 'test' a,'test' b) a); SELECT 1 as a,(SELECT a+a) b,(SELECT b); @@ -63,7 +63,7 @@ create table t4 (a int not null, b int not null); insert into t1 values (2); insert into t2 values (1,7),(2,7); insert into t4 values (4,8),(3,8),(5,9); --- error 1245 +-- error 1246 select (select a from t1 where t1.a = a1) as a2, (select b from t2 where t2.b=a2) as a1; select (select a from t1 where t1.a=t2.a), a from t2; select (select a from t1 where t1.a=t2.b), a from t2; @@ -102,9 +102,9 @@ select * from t3 where a < all (select b from t2); select * from t3 where a >= any (select b from t2); select * from t3 where a >= all (select b from t2); delete from t2 where a=100; --- error 1239 +-- error 1240 select * from t3 where a in (select a,b from t2); --- error 1239 +-- error 1240 select * from t3 where a in (select * from t2); insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9),(1,10); -- empty set @@ -120,7 +120,7 @@ select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a) insert into t5 values (2); select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2; explain select (select a from t1 where t1.a=t2.a union select a from t5 where t5.a=t2.a), a from t2; --- error 1240 +-- error 1241 select (select a from t1 where t1.a=t2.a union all select a from t5 where t5.a=t2.a), a from t2; create table t6 (patient_uq int, clinic_uq int, index i1 (clinic_uq)); create table t7( uq int primary key, name char(25)); @@ -157,14 +157,14 @@ INSERT INTO t8 (pseudo,email) VALUES ('joce','test'); INSERT INTO t8 (pseudo,email) VALUES ('joce1','test1'); INSERT INTO t8 (pseudo,email) VALUES ('2joce1','2test1'); EXPLAIN SELECT pseudo,(SELECT email FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce')) FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); --- error 1239 +-- error 1240 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo,email FROM t8 WHERE pseudo='joce'); --- error 1239 +-- error 1240 SELECT pseudo FROM t8 WHERE pseudo=(SELECT * FROM t8 WHERE pseudo='joce'); SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo='joce'); --- error 1240 +-- error 1241 SELECT pseudo FROM t8 WHERE pseudo=(SELECT pseudo FROM t8 WHERE pseudo LIKE '%joce%'); drop table if exists t1,t2,t3,t4,t5,t6,t7,t8; @@ -184,7 +184,7 @@ EXPLAIN SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03'); SELECT DISTINCT date FROM t1 WHERE date='2002-08-03'; SELECT (SELECT DISTINCT date FROM t1 WHERE date='2002-08-03'); SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1) UNION ALL SELECT 1; --- error 1240 +-- error 1241 SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1) UNION SELECT 1; EXPLAIN SELECT 1 FROM t1 WHERE 1=(SELECT 1 UNION SELECT 1); drop table t1; @@ -241,9 +241,9 @@ CREATE TABLE `t1` ( ) TYPE=MyISAM ROW_FORMAT=FIXED; INSERT INTO t1 (numeropost,maxnumrep) VALUES (1,0),(2,1); --- error 1240 +-- error 1241 select numeropost as a FROM t1 GROUP BY (SELECT 1 FROM t1 HAVING a=1); --- error 1240 +-- error 1241 select numeropost as a FROM t1 ORDER BY (SELECT 1 FROM t1 HAVING a=1); drop table t1; @@ -255,7 +255,7 @@ drop table t1; #iftest CREATE TABLE t1 (field char(1) NOT NULL DEFAULT 'b'); INSERT INTO t1 VALUES (); --- error 1240 +-- error 1241 SELECT field FROM t1 WHERE 1=(SELECT 1 UNION ALL SELECT 1 FROM (SELECT 1) a HAVING field='b'); drop table t1; @@ -268,13 +268,13 @@ CREATE TABLE `t1` ( UNIQUE KEY `numreponse` (`numreponse`), KEY `pseudo` (`pseudo`,`numeropost`) ) TYPE=MyISAM; --- error 1245 +-- error 1246 SELECT (SELECT numeropost FROM t1 HAVING numreponse=a),numreponse FROM (SELECT * FROM t1) as a; -- error 1054 SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=a) FROM (SELECT * FROM t1) as a; SELECT numreponse, (SELECT numeropost FROM t1 HAVING numreponse=1) FROM (SELECT * FROM t1) as a; INSERT INTO t1 (numeropost,numreponse,pseudo) VALUES (1,1,'joce'),(1,2,'joce'),(1,3,'test'); --- error 1240 +-- error 1241 EXPLAIN SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT 1 FROM t1 WHERE numeropost='1'); EXPLAIN SELECT MAX(numreponse) FROM t1 WHERE numeropost='1'; EXPLAIN SELECT numreponse FROM t1 WHERE numeropost='1' AND numreponse=(SELECT MAX(numreponse) FROM t1 WHERE numeropost='1'); @@ -293,7 +293,7 @@ insert into t2 values (1, 21),(2, 22),(3, 23); select * from t1; -- error 1093 update t1 set b= (select b from t1); --- error 1240 +-- error 1241 update t1 set b= (select b from t2); update t1 set b= (select b from t2 where t1.a = t2.a); select * from t1; @@ -308,7 +308,7 @@ select * from t1; select * from t1 where b = (select b from t2 where t1.a = t2.a); -- error 1093 delete from t1 where b = (select b from t1); --- error 1240 +-- error 1241 delete from t1 where b = (select b from t2); delete from t1 where b = (select b from t2 where t1.a = t2.a); select * from t1; @@ -326,7 +326,7 @@ select * from t11; select * from t12; -- error 1093 delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a); --- error 1240 +-- error 1241 delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2); delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); select * from t11; @@ -341,7 +341,7 @@ insert into t2 values (1); insert into t3 values (1),(2); -- error 1093 INSERT INTO t1 (x) VALUES ((SELECT x FROM t1)); --- error 1240 +-- error 1241 INSERT INTO t1 (x) VALUES ((SELECT b FROM t3)); INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); select * from t1; @@ -351,7 +351,6 @@ INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(a) FROM t2)); select * from t1; INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2; select * from t1; --- error 1093 INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; -- error 1054 INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2)); @@ -373,7 +372,7 @@ insert into t3 values (1),(2); select * from t1; -- error 1093 replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2)); --- error 1240 +-- error 1241 replace into t1 (x, y) VALUES ((SELECT a FROM t3), (SELECT a+1 FROM t2)); replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); select * from t1; @@ -409,7 +408,7 @@ INSERT INTO t2 VALUES ((SELECT id FROM t2)); SELECT * FROM t2; CREATE TABLE t1 (id int(11) default NULL, KEY id (id)) TYPE=MyISAM CHARSET=latin1; INSERT INTO t1 values (1),(1); --- error 1240 +-- error 1241 UPDATE t2 SET id=(SELECT * FROM t1); drop table t2, t1; @@ -688,7 +687,7 @@ INSERT INTO t1 VALUES (1); UPDATE t1 SET i=i+(SELECT MAX(i) FROM (SELECT 1) t) WHERE i=(SELECT MAX(i)); -- error 1111 UPDATE t1 SET i=i+1 WHERE i=(SELECT MAX(i)); ---error 1109 +-- error 1109 UPDATE t1 SET t.i=i+(SELECT MAX(i) FROM (SELECT 1) t); drop table t1; diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test index acbc738995f..36bd8eb48e4 100644 --- a/mysql-test/t/type_decimal.test +++ b/mysql-test/t/type_decimal.test @@ -3,6 +3,7 @@ --disable_warnings DROP TABLE IF EXISTS t1; --enable_warnings +SET SQL_WARNINGS=1; CREATE TABLE t1 ( id int(11) NOT NULL auto_increment, diff --git a/mysql-test/t/type_ranges.test b/mysql-test/t/type_ranges.test index ea7fa7be8c1..09b5867e7a8 100644 --- a/mysql-test/t/type_ranges.test +++ b/mysql-test/t/type_ranges.test @@ -5,6 +5,7 @@ --disable_warnings drop table if exists t1,t2,t3; --enable_warnings +SET SQL_WARNINGS=1; CREATE TABLE t1 ( auto int(5) unsigned NOT NULL auto_increment, diff --git a/mysql-test/t/type_uint.test b/mysql-test/t/type_uint.test index b4c88eae95d..ee5f5e8123b 100644 --- a/mysql-test/t/type_uint.test +++ b/mysql-test/t/type_uint.test @@ -5,6 +5,7 @@ --disable_warnings drop table if exists t1; --enable_warnings +SET SQL_WARNINGS=1; create table t1 (this int unsigned); insert into t1 values (1); diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 16a192f1276..22f8406cba5 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -120,7 +120,7 @@ set SESSION query_cache_size=10000; set GLOBAL table_type=DEFAULT; --error 1115 set character_set_client=UNKNOWN_CHARACTER_SET; ---error 1271 +--error 1272 set collation_connection=UNKNOWN_COLLATION; --error 1228 set global autocommit=1; diff --git a/mysql-test/t/warnings.test b/mysql-test/t/warnings.test index 41aa02e925f..050449f0f5b 100644 --- a/mysql-test/t/warnings.test +++ b/mysql-test/t/warnings.test @@ -4,6 +4,7 @@ --disable-warnings drop table if exists t1, t2; --enable-warnings +SET SQL_WARNINGS=1; create table t1 (a int); insert into t1 values (1); diff --git a/scripts/make_win_src_distribution.old b/scripts/make_win_src_distribution.old deleted file mode 100755 index df7ac29ee0d..00000000000 --- a/scripts/make_win_src_distribution.old +++ /dev/null @@ -1,402 +0,0 @@ -#!/bin/sh - -# -# Script to create a Windows src package -# - -version=@VERSION@ -export version -SOURCE=`pwd` -CP="cp -p" - -DEBUG=0 -SILENT=0 -SUFFIX="" -DIRNAME="" -OUTTAR=0 - -# -# This script must run from MySQL top directory -# - -if [ ! -f scripts/make_win_src_distribution ]; then - echo "ERROR : You must run this script from the MySQL top-level directory" - exit 1 -fi - -# -# Check for source compilation/configuration -# - -if [ ! -f sql/sql_yacc.cc ]; then - echo "ERROR : Sorry, you must run this script after the complete build," - echo " hope you know what you are trying to do !!" - exit 1 -fi - -# -# Debug print of the status -# - -print_debug() -{ - for statement - do - if [ "$DEBUG" = "1" ] ; then - echo $statement - fi - done -} - -# -# Usage of the script -# - -show_usage() -{ - echo "MySQL utility script to create a Windows src package, and it takes" - echo "the following arguments:" - echo "" - echo " --debug Debug, without creating the package" - echo " --tmp Specify the temporary location" - echo " --suffix Suffix name for the package" - echo " --dirname Directory name to copy files (intermediate)" - echo " --silent Do not list verbosely files processed" - echo " --tar Create tar.gz package instead of .zip" - echo " --help Show this help message" - - exit 0 -} - -# -# Parse the input arguments -# - -parse_arguments() { - for arg do - case "$arg" in - --debug) DEBUG=1;; - --tmp=*) TMP=`echo "$arg" | sed -e "s;--tmp=;;"` ;; - --suffix=*) SUFFIX=`echo "$arg" | sed -e "s;--suffix=;;"` ;; - --dirname=*) DIRNAME=`echo "$arg" | sed -e "s;--dirname=;;"` ;; - --silent) SILENT=1 ;; - --tar) OUTTAR=1 ;; - --help) show_usage ;; - *) - echo "Unknown argument '$arg'" - exit 1 - ;; - esac - done -} - -parse_arguments "$@" - -# -# Assign the tmp directory if it was set from the environment variables -# - -for i in $TMP $TMPDIR $TEMPDIR $TEMP /tmp -do - if [ "$i" ]; then - print_debug "Setting TMP to '$i'" - TMP=$i - break - fi -done - - -# - -# -# Create a tmp dest directory to copy files -# - -BASE=$TMP/my_win_dist$SUFFIX - -if [ -d $BASE ] ; then - print_debug "Destination directory '$BASE' already exists, deleting it" - rm -r -f $BASE -fi - -$CP -r $SOURCE/VC++Files $BASE -( -find $BASE \( -name "*.dsp" -o -name "*.dsw" \) -and -not -path \*SCCS\* -print -)|( - while read v - do - print_debug "Replacing LF -> CRLF from '$v'" - - # ^M -> type CTRL V + CTRL M - cat $v | sed 's/ //' | sed 's/$/ /' > $v.tmp - rm $v - mv $v.tmp $v - done -) - -# -# Move all error message files to root directory -# - -$CP -r $SOURCE/sql/share $BASE/ -rm -r -f "$BASE/share/Makefile" -rm -r -f "$BASE/share/Makefile.in" -rm -r -f "$BASE/share/Makefile.am" - -# -# Clean up if we did this from a bk tree -# - -if [ -d $BASE/SCCS ] -then - find $BASE/ -type d -name SCCS -printf " \"%p\"" | xargs rm -r -f -fi - -mkdir $BASE/Docs $BASE/extra $BASE/include - - -# -# Copy directory files -# - -copy_dir_files() -{ - for arg do - print_debug "Copying files from directory '$arg'" - cd $SOURCE/$arg - if [ ! -d $BASE/$arg ]; then - print_debug "Creating directory '$arg'" - mkdir $BASE/$arg - fi - for i in *.c *.cpp *.h *.ih *.i *.ic *.asm *.def \ - README INSTALL* LICENSE - do - if [ -f $i ] - then - $CP $SOURCE/$arg/$i $BASE/$arg/$i - fi - done - for i in *.cc - do - if [ -f $i ] - then - i=`echo $i | sed 's/.cc$//g'` - $CP $SOURCE/$arg/$i.cc $BASE/$arg/$i.cpp - fi - done - done -} - -# -# Copy directory contents recursively -# - -copy_dir_dirs() { - - for arg do - - basedir=$arg - - if [ ! -d $BASE/$arg ]; then - mkdir $BASE/$arg - fi - - copy_dir_files $arg - - cd $SOURCE/$arg/ - for i in * - do - if [ -d $SOURCE/$basedir/$i ] && [ "$i" != "SCCS" ]; then - copy_dir_files $basedir/$i - fi - done - done -} - -# -# Input directories to be copied -# - -for i in client dbug extra heap include isam \ - libmysql libmysqld merge myisam \ - myisammrg mysys regex sql strings sql-common \ - vio zlib -do - copy_dir_files $i -done - -# -# Input directories to be copied recursively -# - -for i in bdb innobase -do - copy_dir_dirs $i -done - -# -# Create dummy innobase configure header -# - -if [ -f $BASE/innobase/ib_config.h ]; then - rm -f $BASE/innobase/ib_config.h -fi -touch $BASE/innobase/ib_config.h - - -# -# Copy miscellaneous files -# - -cd $SOURCE -for i in COPYING ChangeLog README \ - INSTALL-SOURCE INSTALL-WIN \ - INSTALL-WIN-SOURCE \ - Docs/manual_toc.html Docs/manual.html \ - Docs/mysqld_error.txt Docs/INSTALL-BINARY - -do - print_debug "Copying file '$i'" - if [ -f $i ] - then - $CP $i $BASE/$i - fi -done - -# -# Fix some windows files -# - -./extra/replace std:: "" -- $BASE/sql/sql_yacc.cpp - -# -# Initialize the initial data directory -# - -if [ -f scripts/mysql_install_db ]; then - print_debug "Initializing the 'data' directory" - scripts/mysql_install_db --no-defaults --windows --datadir=$BASE/data -fi - -# -# Specify the distribution package name and copy it -# - -if test -z $DIRNAME -then - NEW_DIR_NAME=mysql@MYSQL_SERVER_SUFFIX@-$version$SUFFIX -else - NEW_DIR_NAME=$DIRNAME -fi -NEW_NAME=$NEW_DIR_NAME-win-src - -BASE2=$TMP/$NEW_DIR_NAME -rm -r -f $BASE2 -mv $BASE $BASE2 -BASE=$BASE2 - -# -# If debugging, don't create a zip/tar/gz -# - -if [ "$DEBUG" = "1" ] ; then - echo "Please check the distribution files from $BASE" - echo "Exiting (without creating the package).." - exit -fi - -# -# This is needed to prefere gnu tar instead of tar because tar can't -# always handle long filenames -# - -PATH_DIRS=`echo $PATH | sed -e 's/^:/. /' -e 's/:$/ ./' -e 's/::/ . /g' -e 's/:/ /g' ` -which_1 () -{ - for cmd - do - for d in $PATH_DIRS - do - for file in $d/$cmd - do - if test -x $file -a ! -d $file - then - echo $file - exit 0 - fi - done - done - done - exit 1 -} - -# -# Create the result zip/tar file -# - -set_tarzip_options() -{ - for arg - do - if [ "$arg" = "tar" ]; then - ZIPFILE1=gnutar - ZIPFILE2=gtar - OPT=cvf - EXT=".tar" - NEED_COMPRESS=1 - if [ "$SILENT" = "1" ] ; then - OPT=cf - fi - else - ZIPFILE1=zip - ZIPFILE2="" - OPT="-r" - EXT=".zip" - NEED_COMPRESS=0 - if [ "$SILENT" = "1" ] ; then - OPT="$OPT -q" - fi - fi - done -} - -if [ "$OUTTAR" = "1" ]; then - set_tarzip_options 'tar' -else - set_tarzip_options 'zip' -fi - -tar=`which_1 $ZIPFILE1 $ZIPFILE2` -if test "$?" = "1" -o "$tar" = "" -then - print_debug "Search failed for '$ZIPFILE1', '$ZIPFILE2', using default 'tar'" - tar=tar - set_tarzip_options 'tar' -fi - -# -# Create the archive -# - -print_debug "Using $tar to create archive" - -cd $TMP - -rm -f $SOURCE/$NEW_NAME$EXT -$tar $OPT $SOURCE/$NEW_NAME$EXT $NEW_DIR_NAME -cd $SOURCE - -if [ "$NEED_COMPRESS" = "1" ] -then - print_debug "Compressing archive" - gzip -9 $NEW_NAME$EXT - EXT="$EXT.gz" -fi - -print_debug "Removing temporary directory" -rm -r -f $BASE - -if [ "$SILENT" = "0" ] ; then - echo "$NEW_NAME$EXT created successfully !!" -fi -# End of script diff --git a/scripts/make_win_src_distribution.sh b/scripts/make_win_src_distribution.sh index 8f8ee344e93..df7ac29ee0d 100755 --- a/scripts/make_win_src_distribution.sh +++ b/scripts/make_win_src_distribution.sh @@ -219,7 +219,7 @@ copy_dir_dirs() { for i in client dbug extra heap include isam \ libmysql libmysqld merge myisam \ - myisammrg mysys regex sql strings \ + myisammrg mysys regex sql strings sql-common \ vio zlib do copy_dir_files $i diff --git a/sql-common/client.c b/sql-common/client.c index f9219e5418d..222f0bf0288 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -134,6 +134,10 @@ const char *def_shared_memory_base_name= default_shared_memory_base_name; static void mysql_close_free_options(MYSQL *mysql); static void mysql_close_free(MYSQL *mysql); +#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__)) +static int wait_for_data(my_socket fd, uint timeout); +#endif + /**************************************************************************** A modified version of connect(). my_connect() allows you to specify a timeout value, in seconds, that we should wait until we @@ -143,17 +147,13 @@ static void mysql_close_free(MYSQL *mysql); Base version coded by Steve Bernacki, Jr. *****************************************************************************/ -my_bool my_connect(my_socket s, const struct sockaddr *name, - uint namelen, uint timeout) +int my_connect(my_socket fd, const struct sockaddr *name, uint namelen, + uint timeout) { #if defined(__WIN__) || defined(OS2) || defined(__NETWARE__) - return connect(s, (struct sockaddr*) name, namelen) != 0; + return connect(fd, (struct sockaddr*) name, namelen); #else int flags, res, s_err; - SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); - fd_set sfds; - struct timeval tv; - time_t start_time, now_time; /* If they passed us a timeout of zero, we should behave @@ -161,60 +161,98 @@ my_bool my_connect(my_socket s, const struct sockaddr *name, */ if (timeout == 0) - return connect(s, (struct sockaddr*) name, namelen) != 0; + return connect(fd, (struct sockaddr*) name, namelen); - flags = fcntl(s, F_GETFL, 0); /* Set socket to not block */ + flags = fcntl(fd, F_GETFL, 0); /* Set socket to not block */ #ifdef O_NONBLOCK - fcntl(s, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */ + fcntl(fd, F_SETFL, flags | O_NONBLOCK); /* and save the flags.. */ #endif - res = connect(s, (struct sockaddr*) name, namelen); - s_err = errno; /* Save the error... */ - fcntl(s, F_SETFL, flags); + res= connect(fd, (struct sockaddr*) name, namelen); + s_err= errno; /* Save the error... */ + fcntl(fd, F_SETFL, flags); if ((res != 0) && (s_err != EINPROGRESS)) { - errno = s_err; /* Restore it */ - return(1); + errno= s_err; /* Restore it */ + return(-1); } if (res == 0) /* Connected quickly! */ return(0); + return wait_for_data(fd, timeout); +#endif +} + + +/* + Wait up to timeout seconds for a connection to be established. + + We prefer to do this with poll() as there is no limitations with this. + If not, we will use select() +*/ + +#if !(defined(__WIN__) || defined(OS2) || defined(__NETWARE__)) + +static int wait_for_data(my_socket fd, uint timeout) +{ +#ifdef HAVE_POLL + struct pollfd ufds; + int res; + + ufds.fd= fd; + ufds.events= POLLIN | POLLPRI; + if (!(res= poll(&ufds, 1, (int) timeout*1000))) + { + errno= EINTR; + return -1; + } + if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI))) + return -1; + return 0; +#else + SOCKOPT_OPTLEN_TYPE s_err_size = sizeof(uint); + fd_set sfds; + struct timeval tv; + time_t start_time, now_time; + int res, s_err; + + if (fd >= FD_SETSIZE) /* Check if wrong error */ + return 0; /* Can't use timeout */ /* - Otherwise, our connection is "in progress." We can use - the select() call to wait up to a specified period of time - for the connection to succeed. If select() returns 0 - (after waiting howevermany seconds), our socket never became - writable (host is probably unreachable.) Otherwise, if + Our connection is "in progress." We can use the select() call to wait + up to a specified period of time for the connection to suceed. + If select() returns 0 (after waiting howevermany seconds), our socket + never became writable (host is probably unreachable.) Otherwise, if select() returns 1, then one of two conditions exist: - + 1. An error occured. We use getsockopt() to check for this. 2. The connection was set up sucessfully: getsockopt() will return 0 as an error. - + Thanks goes to Andrew Gierth who posted this method of timing out a connect() in comp.unix.programmer on August 15th, 1997. */ FD_ZERO(&sfds); - FD_SET(s, &sfds); + FD_SET(fd, &sfds); /* - select could be interrupted by a signal, and if it is, + select could be interrupted by a signal, and if it is, the timeout should be adjusted and the select restarted - to work around OSes that don't restart select and + to work around OSes that don't restart select and implementations of select that don't adjust tv upon failure to reflect the time remaining - */ + */ start_time = time(NULL); for (;;) { tv.tv_sec = (long) timeout; tv.tv_usec = 0; #if defined(HPUX10) && defined(THREAD) - if ((res = select(s+1, NULL, (int*) &sfds, NULL, &tv)) > 0) + if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0) break; #else - if ((res = select(s+1, NULL, &sfds, NULL, &tv)) > 0) + if ((res = select(fd+1, NULL, &sfds, NULL, &tv)) > 0) break; #endif if (res == 0) /* timeout */ @@ -222,7 +260,7 @@ my_bool my_connect(my_socket s, const struct sockaddr *name, now_time=time(NULL); timeout-= (uint) (now_time - start_time); if (errno != EINTR || (int) timeout <= 0) - return 1; + return -1; } /* @@ -232,18 +270,19 @@ my_bool my_connect(my_socket s, const struct sockaddr *name, */ s_err=0; - if (getsockopt(s, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) - return(1); + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &s_err, &s_err_size) != 0) + return(-1); if (s_err) { /* getsockopt could succeed */ errno = s_err; - return(1); /* but return an error... */ + return(-1); /* but return an error... */ } return (0); /* ok */ - -#endif +#endif /* HAVE_POLL */ } +#endif /* defined(__WIN__) || defined(OS2) || defined(__NETWARE__) */ + /* Create a named pipe connection @@ -1452,6 +1491,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, struct sockaddr_in sock_addr; ulong pkt_length; NET *net= &mysql->net; + uint charset_number; #ifdef MYSQL_SERVER thr_alarm_t alarmed; ALARM alarm_buff; @@ -1744,17 +1784,19 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->server_language=end[2]; mysql->server_status=uint2korr(end+3); } + charset_number= mysql->server_language; /* Set character set */ if ((charset_name=mysql->options.charset_name)) { - const char *save=charsets_dir; + const char *save= charsets_dir; if (mysql->options.charset_dir) charsets_dir=mysql->options.charset_dir; mysql->charset=get_charset_by_csname(mysql->options.charset_name, MY_CS_PRIMARY, MYF(MY_WME)); - charsets_dir=save; + charset_number= mysql->charset ? mysql->charset->number : 0; + charsets_dir= save; } else if (mysql->server_language) { @@ -1766,7 +1808,10 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->charset = default_charset_info; /* shouldn't be fatal */ } else - mysql->charset=default_charset_info; + { + mysql->charset= default_charset_info; + charset_number= mysql->charset->number; + } if (!mysql->charset) { @@ -1846,7 +1891,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, /* 4.1 server and 4.1 client has a 32 byte option flag */ int4store(buff,client_flag); int4store(buff+4, net->max_packet_size); - buff[8]= mysql->charset->number; + buff[8]= (char) charset_number; bzero(buff+9, 32-9); end= buff+32; } diff --git a/sql/field.cc b/sql/field.cc index 2f89dd43c3f..c972c116b1c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3905,7 +3905,8 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) { memcpy(ptr,from,length); if (length < field_length) - field_charset->cset->fill(field_charset,ptr+length,field_length-length,' '); + field_charset->cset->fill(field_charset,ptr+length,field_length-length, + ' '); } else { @@ -3914,7 +3915,8 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) { // Check if we loosed some info const char *end=from+length; from+= field_length; - from+= field_charset->cset->scan(field_charset, from, end, MY_SEQ_SPACES); + from+= field_charset->cset->scan(field_charset, from, end, + MY_SEQ_SPACES); if (from != end) { set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED); @@ -5147,7 +5149,8 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) from= tmpstr.ptr(); length= tmpstr.length(); } - ulonglong tmp= find_set(typelib, from, length, ¬_used, ¬_used2, &set_warning); + ulonglong tmp= find_set(typelib, from, length, ¬_used, ¬_used2, + &set_warning); if (!tmp && length && length < 22) { /* This is for reading numbers with LOAD DATA INFILE */ @@ -5157,10 +5160,14 @@ int Field_set::store(const char *from,uint length,CHARSET_INFO *cs) tmp > (ulonglong) (((longlong) 1 << typelib->count) - (longlong) 1)) { tmp=0; - current_thd->cuted_fields++; - push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED), - field_name, 0); + THD *thd= current_thd; + if (thd->count_cuted_fields) + { + thd->cuted_fields++; + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED), + field_name, 0); + } } } store_type(tmp); @@ -5496,7 +5503,10 @@ create_field::create_field(Field *old_field,Field *orig_field) void Field::set_warning(const uint level, const uint code) { THD *thd= current_thd; - thd->cuted_fields++; - push_warning_printf(thd, (MYSQL_ERROR::enum_warning_level) level, - code, ER(code), field_name, thd->row_count); + if (thd->count_cuted_fields) + { + thd->cuted_fields++; + push_warning_printf(thd, (MYSQL_ERROR::enum_warning_level) level, + code, ER(code), field_name, thd->row_count); + } } diff --git a/sql/ha_myisammrg.h b/sql/ha_myisammrg.h index cfe4b47ef10..008f5339caf 100644 --- a/sql/ha_myisammrg.h +++ b/sql/ha_myisammrg.h @@ -40,8 +40,7 @@ class ha_myisammrg: public handler } ulong index_flags(uint inx) const { - ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | - HA_NOT_READ_PREFIX_LAST); // This - last - flag is ONLY for 4.0 !!! + ulong flags=(HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER); return (flags | ((table->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ? 0 : HA_KEY_READ_ONLY)); } diff --git a/sql/log.cc b/sql/log.cc index b3f7e753010..d3ba5b63e19 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -763,9 +763,6 @@ int MYSQL_LOG::purge_logs(const char *to_log, DBUG_ENTER("purge_logs"); DBUG_PRINT("info",("to_log= %s",to_log)); - if (no_rotate) - DBUG_RETURN(LOG_INFO_PURGE_NO_ROTATE); - if (need_mutex) pthread_mutex_lock(&LOCK_index); if ((error=find_log_pos(&log_info, to_log, 0 /*no mutex*/))) diff --git a/sql/log_event.cc b/sql/log_event.cc index 9f7d09785ac..3b04baf7ae7 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -102,13 +102,13 @@ static char *pretty_print_str(char *packet, char *str, int len) { char c; switch ((c=*str++)) { - case '\n': *pos++= '\'; *pos++= 'n'; break; - case '\r': *pos++= '\'; *pos++= 'r'; break; - case '\\': *pos++= '\'; *pos++= '\'; break; - case '\b': *pos++= '\'; *pos++= 'b'; break; - case '\t': *pos++= '\'; *pos++= 't'; break; - case '\'': *pos++= '\'; *pos++= '\''; break; - case 0 : *pos++= '\'; *pos++= '0'; break; + case '\n': *pos++= '\\'; *pos++= 'n'; break; + case '\r': *pos++= '\\'; *pos++= 'r'; break; + case '\\': *pos++= '\\'; *pos++= '\\'; break; + case '\b': *pos++= '\\'; *pos++= 'b'; break; + case '\t': *pos++= '\\'; *pos++= 't'; break; + case '\'': *pos++= '\\'; *pos++= '\''; break; + case 0 : *pos++= '\\'; *pos++= '0'; break; default: *pos++= c; break; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index b5afbb422d5..4305706f3dc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2176,7 +2176,7 @@ static int init_server_components() if (opt_update_log) { open_log(&mysql_update_log, glob_hostname, opt_update_logname, "", -! NullS, LOG_NEW, 0, 0, 0); + NullS, LOG_NEW, 0, 0, 0); using_update_log=1; } if (opt_slow_log) @@ -5470,7 +5470,11 @@ static void get_options(int argc,char **argv) files_charset_info : &my_charset_bin); /* QQ To be deleted when we have key cache variables in a struct */ - keybuff_size= (((KEY_CACHE *) find_named(&key_caches, "default", 7))->size); + { + NAMED_LIST *not_used; + keybuff_size= (((KEY_CACHE *) find_named(&key_caches, "default", 7, + ¬_used))->size); + } } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 839804b20d5..23fb36c0c91 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2392,7 +2392,7 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref) return 0; if (cp_buffer_from_ref(ref)) { - if (current_thd->fatal_error) + if (current_thd->is_fatal_error) return 0; // End of memory return quick; // empty range } diff --git a/sql/set_var.cc b/sql/set_var.cc index eebefc8b79c..499eed132a7 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -823,8 +823,10 @@ void fix_max_binlog_size(THD *thd, enum_var_type type) DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", max_binlog_size, max_relay_log_size)); mysql_bin_log.set_max_size(max_binlog_size); +#ifdef REPLICATION if (!max_relay_log_size) active_mi->rli.relay_log.set_max_size(max_binlog_size); +#endif DBUG_VOID_RETURN; } @@ -1090,12 +1092,6 @@ err: } -void sys_var_thd_conv_charset::set_default(THD *thd, enum_var_type type) -{ - thd->variables.convert_set= global_system_variables.convert_set; -} - - bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) { bool not_used; @@ -1107,8 +1103,10 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names) { if (!(res= var->value->val_str(&str))) goto err; - var->save_result.ulong_value= (ulong) - find_set(enum_names, res->c_ptr(), res->length(), &error, &error_len, ¬_used); + var->save_result.ulong_value= ((ulong) + find_set(enum_names, res->c_ptr(), + res->length(), &error, &error_len, + ¬_used)); if (error_len) { strmake(buff, error, min(sizeof(buff), error_len)); @@ -1254,16 +1252,17 @@ static my_old_conv old_conv[]= CHARSET_INFO *get_old_charset_by_name(const char *name) { - my_old_conv *c; + my_old_conv *conv; - for (c= old_conv; c->old_name; c++) + for (conv= old_conv; conv->old_name; conv++) { - if (!my_strcasecmp(&my_charset_latin1,name,c->old_name)) - return get_charset_by_csname(c->new_name,MY_CS_PRIMARY,MYF(0)); + if (!my_strcasecmp(&my_charset_latin1, name, conv->old_name)) + return get_charset_by_csname(conv->new_name, MY_CS_PRIMARY, MYF(0)); } return NULL; } + bool sys_var_collation::check(THD *thd, set_var *var) { CHARSET_INFO *tmp; @@ -1299,7 +1298,7 @@ bool sys_var_character_set::check(THD *thd, set_var *var) tmp= NULL; } else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) && - !(tmp=get_old_charset_by_name(res->c_ptr()))) + !(tmp=get_old_charset_by_name(res->c_ptr()))) { my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr()); return 1; @@ -1340,7 +1339,10 @@ void sys_var_character_set_connection::set_default(THD *thd, if (type == OPT_GLOBAL) global_system_variables.collation_connection= default_charset_info; else + { thd->variables.collation_connection= global_system_variables.collation_connection; + thd->update_charset(); + } } @@ -1359,11 +1361,16 @@ void sys_var_character_set_client::set_default(THD *thd, enum_var_type type) if (type == OPT_GLOBAL) global_system_variables.character_set_client= default_charset_info; else - thd->variables.character_set_client= global_system_variables.character_set_client; + { + thd->variables.character_set_client= (global_system_variables. + character_set_client); + thd->update_charset(); + } } -CHARSET_INFO ** sys_var_character_set_results::ci_ptr(THD *thd, enum_var_type type) +CHARSET_INFO ** +sys_var_character_set_results::ci_ptr(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) return &global_system_variables.character_set_results; @@ -1377,11 +1384,16 @@ void sys_var_character_set_results::set_default(THD *thd, enum_var_type type) if (type == OPT_GLOBAL) global_system_variables.character_set_results= default_charset_info; else - thd->variables.character_set_results= global_system_variables.character_set_results; + { + thd->variables.character_set_results= (global_system_variables. + character_set_results); + thd->update_charset(); + } } -CHARSET_INFO ** sys_var_character_set_server::ci_ptr(THD *thd, enum_var_type type) +CHARSET_INFO ** +sys_var_character_set_server::ci_ptr(THD *thd, enum_var_type type) { if (type == OPT_GLOBAL) return &global_system_variables.character_set_server; @@ -1395,7 +1407,11 @@ void sys_var_character_set_server::set_default(THD *thd, enum_var_type type) if (type == OPT_GLOBAL) global_system_variables.character_set_server= default_charset_info; else - thd->variables.character_set_server= global_system_variables.character_set_server; + { + thd->variables.character_set_server= (global_system_variables. + character_set_server); + thd->update_charset(); + } } @@ -1414,7 +1430,10 @@ void sys_var_character_set_database::set_default(THD *thd, enum_var_type type) if (type == OPT_GLOBAL) global_system_variables.character_set_database= default_charset_info; else + { thd->variables.character_set_database= thd->db_charset; + thd->update_charset(); + } } @@ -1423,7 +1442,10 @@ bool sys_var_collation_connection::update(THD *thd, set_var *var) if (var->type == OPT_GLOBAL) global_system_variables.collation_connection= var->save_result.charset; else + { thd->variables.collation_connection= var->save_result.charset; + thd->update_charset(); + } return 0; } @@ -1443,38 +1465,47 @@ void sys_var_collation_connection::set_default(THD *thd, enum_var_type type) if (type == OPT_GLOBAL) global_system_variables.collation_connection= default_charset_info; else - thd->variables.collation_connection= global_system_variables.collation_connection; + { + thd->variables.collation_connection= (global_system_variables. + collation_connection); + thd->update_charset(); + } } bool sys_var_key_buffer_size::update(THD *thd, set_var *var) { ulonglong tmp= var->value->val_int(); - if (!base_name.length) + NAMED_LIST *list; + LEX_STRING *base_name= &var->base; + + if (!base_name->length) { - base_name.str= (char*) "default"; - base_name.length= 7; + /* We are using SET KEY_BUFFER_SIZE=# */ + base_name->str= (char*) "default"; + base_name->length= 7; } - KEY_CACHE *key_cache= (KEY_CACHE*) find_named(&key_caches, base_name.str, - base_name.length); + KEY_CACHE *key_cache= (KEY_CACHE*) find_named(&key_caches, base_name->str, + base_name->length, &list); if (!key_cache) { if (!tmp) // Tried to delete cache return 0; // Ok, nothing to do - if (!(key_cache= create_key_cache(base_name.str, - base_name.length))) + if (!(key_cache= create_key_cache(base_name->str, + base_name->length))) return 1; } - if (!tmp) + if (!tmp) // Zero size means delete { - /* Delete not default key caches */ - if (base_name.length != 7 || memcpy(base_name.str, "default", 7)) + /* Don't delete the default key cache */ + if (base_name->length != 7 || memcmp(base_name->str, "default", 7)) { /* - QQ: Here we should move tables using this key cache to default - key cache + QQ: Here we should move tables that is using the found key cache + to the default key cache */ - delete key_cache; + delete list; + my_free((char*) key_cache, MYF(0)); return 0; } } @@ -1487,6 +1518,7 @@ bool sys_var_key_buffer_size::update(THD *thd, set_var *var) return 0; } + static ulonglong zero=0; byte *sys_var_key_buffer_size::value_ptr(THD *thd, enum_var_type type, @@ -1494,6 +1526,8 @@ byte *sys_var_key_buffer_size::value_ptr(THD *thd, enum_var_type type, { const char *name; uint length; + KEY_CACHE *key_cache; + NAMED_LIST *not_used; if (!base->str) { @@ -1505,7 +1539,7 @@ byte *sys_var_key_buffer_size::value_ptr(THD *thd, enum_var_type type, name= base->str; length= base->length; } - KEY_CACHE *key_cache= (KEY_CACHE*) find_named(&key_caches, name, length); + key_cache= (KEY_CACHE*) find_named(&key_caches, name, length, ¬_used); if (!key_cache) return (byte*) &zero; return (byte*) &key_cache->size; @@ -1527,6 +1561,7 @@ int set_var_collation_client::update(THD *thd) thd->variables.character_set_client= character_set_client; thd->variables.character_set_results= character_set_results; thd->variables.collation_connection= collation_connection; + thd->update_charset(); thd->protocol_simple.init(thd); thd->protocol_prep.init(thd); return 0; @@ -1860,17 +1895,18 @@ int sql_set_variables(THD *thd, List *var_list) { int error= 0; List_iterator_fast it(*var_list); + DBUG_ENTER("sql_set_variables"); set_var_base *var; while ((var=it++)) { if ((error=var->check(thd))) - return error; + DBUG_RETURN(error); } it.rewind(); while ((var=it++)) error|= var->update(thd); // Returns 0, -1 or 1 - return error; + DBUG_RETURN(error); } @@ -2071,14 +2107,18 @@ ulong fix_sql_mode(ulong sql_mode) Named list handling ****************************************************************************/ -gptr find_named(I_List *list, const char *name, uint length) +gptr find_named(I_List *list, const char *name, uint length, + NAMED_LIST **found) { I_List_iterator it(*list); NAMED_LIST *element; while ((element= it++)) { if (element->cmp(name, length)) + { + *found= element; return element->data; + } } return 0; } @@ -2087,11 +2127,13 @@ gptr find_named(I_List *list, const char *name, uint length) void delete_elements(I_List *list, void (*free_element)(gptr)) { NAMED_LIST *element; + DBUG_ENTER("delete_elements"); while ((element= list->get())) { (*free_element)(element->data); delete element; } + DBUG_VOID_RETURN; } @@ -2100,7 +2142,8 @@ void delete_elements(I_List *list, void (*free_element)(gptr)) static KEY_CACHE *create_key_cache(const char *name, uint length) { KEY_CACHE *key_cache; - DBUG_PRINT("info",("Creating key cache: %s", name)); + DBUG_PRINT("info",("Creating key cache: %.*s length: %d", length, name, + length)); if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE), MYF(MY_ZEROFILL | MY_WME)))) { @@ -2116,8 +2159,9 @@ static KEY_CACHE *create_key_cache(const char *name, uint length) KEY_CACHE *get_or_create_key_cache(const char *name, uint length) { + NAMED_LIST *not_used; KEY_CACHE *key_cache= (KEY_CACHE*) find_named(&key_caches, name, - length); + length, ¬_used); if (!key_cache) key_cache= create_key_cache(name, length); return key_cache; diff --git a/sql/set_var.h b/sql/set_var.h index f9c5d8f7822..f06b5ed22d3 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -47,18 +47,13 @@ public: struct my_option *option_limits; /* Updated by by set_var_init() */ uint name_length; /* Updated by by set_var_init() */ const char *name; - LEX_STRING base_name; /* for structs */ sys_after_update_func after_update; sys_var(const char *name_arg) :name(name_arg),after_update(0) - { - base_name.length=0; - } + {} sys_var(const char *name_arg,sys_after_update_func func) :name(name_arg),after_update(func) - { - base_name.length=0; - } + {} virtual ~sys_var() {} virtual bool check(THD *thd, set_var *var) { return 0; } bool check_enum(THD *thd, set_var *var, TYPELIB *enum_names); @@ -167,7 +162,6 @@ public: return type != STRING_RESULT; /* Only accept strings */ } bool check_default(enum_var_type type) { return 0; } - void set_default(THD *thd, enum_var_type type); }; @@ -596,9 +590,11 @@ public: CHARSET_INFO *charset; ulong ulong_value; } save_result; + LEX_STRING base; /* for structs */ - set_var(enum_var_type type_arg, sys_var *var_arg, Item *value_arg) - :var(var_arg), type(type_arg) + set_var(enum_var_type type_arg, sys_var *var_arg, LEX_STRING *base_name_arg, + Item *value_arg) + :var(var_arg), type(type_arg), base(*base_name_arg) { /* If the set value is a field, change it to a string to allow things like @@ -677,12 +673,12 @@ public: gptr data; NAMED_LIST(I_List *links, const char *name_arg, - uint name_length_arg, gptr data_arg): - name_length(name_length_arg), data(data_arg) - { - name=my_strdup(name_arg,MYF(MY_WME)); - links->push_back(this); - } + uint name_length_arg, gptr data_arg) + :name_length(name_length_arg), data(data_arg) + { + name= my_memdup(name_arg, name_length, MYF(MY_WME)); + links->push_back(this); + } inline bool cmp(const char *name_cmp, uint length) { return length == name_length && !memcmp(name, name_cmp, length); @@ -694,6 +690,13 @@ public: }; +/* For sql_yacc */ +struct sys_var_with_base +{ + sys_var *var; + LEX_STRING base_name; +}; + /* Prototypes for helper functions */ @@ -706,7 +709,8 @@ void fix_delay_key_write(THD *thd, enum_var_type type); ulong fix_sql_mode(ulong sql_mode); extern sys_var_str sys_charset_system; CHARSET_INFO *get_old_charset_by_name(const char *old_name); -gptr find_named(I_List *list, const char *name, uint length); +gptr find_named(I_List *list, const char *name, uint length, + NAMED_LIST **found); void delete_elements(I_List *list, void (*free_element)(gptr)); /* key_cache functions */ diff --git a/sql/slave.cc b/sql/slave.cc index a6c86b08010..16d493f1667 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1442,7 +1442,8 @@ Failed to open the existing relay log info file '%s' (errno %d)", { char llbuf[22]; sql_print_error("Failed to open the relay log '%s' (relay_log_pos %s)", - rli->relay_log_name, llstr(rli->relay_log_pos, llbuf)); + rli->group_relay_log_name, + llstr(rli->group_relay_log_pos, llbuf)); goto err; } } @@ -3491,10 +3492,9 @@ Log_event* next_event(RELAY_LOG_INFO* rli) it */ DBUG_PRINT("info", ("\ -Before assert, my_b_tell(cur_log)=%s rli->relay_log_pos=%s rli->pending=%lu", +Before assert, my_b_tell(cur_log)=%s rli->event_relay_log_pos=%s", llstr(my_b_tell(cur_log),llbuf1), - llstr(rli->relay_log_pos,llbuf2), - rli->pending)); + llstr(rli->group_relay_log_pos,llbuf2))); DBUG_ASSERT(my_b_tell(cur_log) == rli->event_relay_log_pos); } #endif diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 08212bbf65b..9738c0c5d9e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2353,8 +2353,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list, } -int mysql_grant (THD *thd, const char *db, List &list, - ulong rights, bool revoke_grant) +int mysql_grant(THD *thd, const char *db, List &list, + ulong rights, bool revoke_grant) { List_iterator str_list (list); LEX_USER *Str; @@ -2364,8 +2364,8 @@ int mysql_grant (THD *thd, const char *db, List &list, DBUG_ENTER("mysql_grant"); if (!initialized) { - send_error(thd, ER_UNKNOWN_COM_ERROR); /* purecov: tested */ - return 1; /* purecov: tested */ + my_error(ER_UNKNOWN_COM_ERROR, MYF(0)); /* purecov: tested */ + return -1; /* purecov: tested */ } if (lower_case_table_names && db) @@ -2443,7 +2443,8 @@ int mysql_grant (THD *thd, const char *db, List &list, } else { - net_printf(&thd->net,ER_WRONG_USAGE,"DB GRANT","GLOBAL PRIVILEGES"); + my_printf_error(ER_WRONG_USAGE, ER(ER_WRONG_USAGE), MYF(0), + "DB GRANT","GLOBAL PRIVILEGES"); result= -1; } } @@ -2941,7 +2942,8 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) ulong want_access; uint counter,index; int error = 0; - ACL_USER *acl_user; ACL_DB *acl_db; + ACL_USER *acl_user; + ACL_DB *acl_db; char buff[1024]; Protocol *protocol= thd->protocol; DBUG_ENTER("mysql_show_grants"); @@ -2993,11 +2995,11 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) /* Add first global access grants */ { - want_access=acl_user->access; String global(buff,sizeof(buff),&my_charset_latin1); global.length(0); global.append("GRANT ",6); + want_access= acl_user->access; if (test_all_bits(want_access, (GLOBAL_ACLS & ~ GRANT_ACL))) global.append("ALL PRIVILEGES",14); else if (!(want_access & ~GRANT_ACL)) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c233ffd422a..c29e7ca2213 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -385,6 +385,59 @@ bool THD::store_globals() } +/* + Convert a string to another character set + + SYNOPSIS + convert_string() + to Store new allocated string here + to_cs New character set for allocated string + from String to convert + from_length Length of string to convert + from_cs Original character set + + NOTES + to will be 0-terminated to make it easy to pass to system funcs + + RETURN + 0 ok + 1 End of memory. + In this case to->str will point to 0 and to->length will be 0. +*/ + +bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs, + const char *from, uint from_length, + CHARSET_INFO *from_cs) +{ + DBUG_ENTER("convert_string"); + size_s new_length= to_cs->mbmaxlen * from_length; + if (!(to->str= alloc(new_length+1))) + { + to->length= 0; // Safety fix + DBUG_RETURN(1); // EOM + } + to->length= copy_and_convert((char*) to->str, new_length, to_cs, + from, from_length, from_cs); + to->str[to->length]=0; // Safety + DBUG_RETURN(0); +} + + +/* + Update some cache variables when character set changes +*/ + +void THD::update_charset() +{ + charset_is_system_charset= my_charset_same(charset(),system_charset_info); + charset_is_collation_connection= my_charset_same(charset(), + variables. + collation_connection); +} + + + + /* routings to adding tables to list of changed in transaction tables */ inline static void list_include(CHANGED_TABLE_LIST** prev, diff --git a/sql/sql_class.h b/sql/sql_class.h index 414b4eac6a6..fe896a50c4f 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -571,6 +571,7 @@ public: bool volatile killed; bool prepare_command; bool tmp_table_used; + bool charset_is_system_charset, charset_is_collation_connection; /* If we do a purge of binary logs, log index info of the threads @@ -678,6 +679,9 @@ public: memcpy(ptr,str,size); return ptr; } + bool convert_string(LEX_STRING *to, CHARSET_INFO *to_cs, + const char *from, uint from_length, + CHARSET_INFO *from_cs); inline gptr trans_alloc(unsigned int size) { return alloc_root(&transaction.mem_root,size); @@ -703,6 +707,7 @@ public: DBUG_PRINT("error",("Fatal error set")); } inline CHARSET_INFO *charset() { return variables.character_set_client; } + void update_charset(); }; /* diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 0387f02e83f..93ab332bcd5 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -203,7 +203,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, Item *item; for (key_len=0 ; (item=it_ke++) ; key_part++) { - if (item->fix_fields(thd, tables)) + if (item->fix_fields(thd, tables, &item)) goto err; if (item->used_tables() & ~RAND_TABLE_BIT) { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 03a0f7beda9..506818cdcf9 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -225,6 +225,8 @@ public: { return (void*) sql_alloc((uint) size); } + static void *operator new(size_t size, MEM_ROOT *mem_root) + { return (void*) alloc_root(mem_root, (uint) size); } static void operator delete(void *ptr,size_t size) {} st_select_lex_node(): linkage(UNSPECIFIED_TYPE) {} virtual ~st_select_lex_node() {} diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d9f6b93d2bb..e8df7c39c70 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -549,8 +549,8 @@ check_connections(THD *thd) NET *net= &thd->net; char *end, *user, *passwd, *db; char prepared_scramble[SCRAMBLE41_LENGTH+4]; /* Buffer for scramble&hash */ + char db_buff[NAME_LEN+1]; ACL_USER* cached_user=NULL; /* Initialise to NULL for first stage */ - String convdb; DBUG_PRINT("info",("New connection received on %s", vio_description(net->vio))); @@ -667,8 +667,18 @@ check_connections(THD *thd) { thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16; thd->max_client_packet_length= uint4korr(net->read_pos+4); + DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8])); + /* + Use server character set and collation if + - client has not specified a character set + - client character set is the same as the servers + - client character set doesn't exists in server + */ if (!(thd->variables.character_set_client= - get_charset((uint) net->read_pos[8], MYF(0)))) + get_charset((uint) net->read_pos[8], MYF(0))) || + !my_strcasecmp(&my_charset_latin1, + global_system_variables.character_set_client->name, + thd->variables.character_set_client->name)) { thd->variables.character_set_client= global_system_variables.character_set_client; @@ -683,6 +693,7 @@ check_connections(THD *thd) thd->variables.collation_connection= thd->variables.character_set_client; } + thd->update_charset(); end= (char*) net->read_pos+32; } else @@ -735,10 +746,13 @@ check_connections(THD *thd) using_password= test(passwd[0]); if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB) { - db=strend(passwd)+1; - convdb.copy(db, strlen(db), - thd->variables.character_set_client, system_charset_info); - db= convdb.c_ptr(); + db= strend(passwd)+1; + uint32 length= copy_and_convert(db_buff, sizeof(db_buff)-1, + system_charset_info, + db, strlen(db), + thd->charset()); + db_buff[length]= 0; + db= db_buff; } /* We can get only old hash at this point */ @@ -1140,15 +1154,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->lex.select_lex.options=0; // We store status here switch (command) { case COM_INIT_DB: - { - String convname; - statistic_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_status); - convname.copy(packet, strlen(packet), - thd->variables.character_set_client, system_charset_info); - if (!mysql_change_db(thd,convname.c_ptr())) - mysql_log.write(thd,command,"%s",thd->db); - break; - } + { + LEX_STRING tmp; + statistic_increment(com_stat[SQLCOM_CHANGE_DB],&LOCK_status); + thd->convert_string(&tmp, system_charset_info, + packet, strlen(packet), thd->charset()); + if (!mysql_change_db(thd, tmp.str)) + mysql_log.write(thd,command,"%s",thd->db); + break; + } #ifndef EMBEDDED_LIBRARY case COM_REGISTER_SLAVE: { @@ -1360,8 +1374,9 @@ restore_user: #else { char *fields, *pend; - String convname; TABLE_LIST table_list; + LEX_STRING conv_name; + statistic_increment(com_stat[SQLCOM_SHOW_FIELDS],&LOCK_status); bzero((char*) &table_list,sizeof(table_list)); if (!(table_list.db=thd->db)) @@ -1371,9 +1386,9 @@ restore_user: } thd->free_list=0; pend= strend(packet); - convname.copy(packet, pend-packet, - thd->variables.character_set_client, system_charset_info); - table_list.alias= table_list.real_name= convname.c_ptr(); + thd->convert_string(&conv_name, system_charset_info, + packet, (uint) (pend-packet), thd->charset()); + table_list.alias= table_list.real_name= conv_name.str; packet= pend+1; // command not cachable => no gap for data base name if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1))) @@ -2697,7 +2712,7 @@ mysql_execute_command(THD *thd) goto error; /* purecov: inspected */ if (!thd->col_access && check_grant_db(thd,db)) { - net_printf(&thd->net,ER_DBACCESS_DENIED_ERROR, + net_printf(thd, ER_DBACCESS_DENIED_ERROR, thd->priv_user, thd->priv_host, db); @@ -3195,16 +3210,16 @@ mysql_execute_command(THD *thd) if (!ha_rollback_to_savepoint(thd, lex->savepoint_name)) { if (thd->options & OPTION_STATUS_NO_TRANS_UPDATE) - send_warning(&thd->net,ER_WARNING_NOT_COMPLETE_ROLLBACK,0); + send_warning(thd, ER_WARNING_NOT_COMPLETE_ROLLBACK, 0); else - send_ok(&thd->net); + send_ok(thd); } else res= -1; break; case SQLCOM_SAVEPOINT: if (!ha_savepoint(thd, lex->savepoint_name)) - send_ok(&thd->net); + send_ok(thd); else res= -1; break; @@ -3584,7 +3599,7 @@ mysql_init_select(LEX *lex) bool mysql_new_select(LEX *lex, bool move_down) { - SELECT_LEX *select_lex = new SELECT_LEX(); + SELECT_LEX *select_lex = new(&lex->thd->mem_root) SELECT_LEX(); if (!select_lex) return 1; select_lex->select_number= ++lex->thd->select_number; @@ -3658,7 +3673,7 @@ void mysql_init_multi_delete(LEX *lex) mysql_init_select(lex); lex->select_lex.select_limit= lex->unit.select_limit_cnt= HA_POS_ERROR; - lex->select->table_list.save_and_clear(&lex->auxilliary_table_list); + lex->select_lex.table_list.save_and_clear(&lex->auxilliary_table_list); } diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index faf128d5e02..3cdf033c477 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -295,14 +295,14 @@ int purge_master_logs(THD* thd, const char* to_log) char search_file_name[FN_REFLEN]; if (!mysql_bin_log.is_open()) { - send_ok(); + send_ok(current_thd); return 0; } mysql_bin_log.make_log_name(search_file_name, to_log); return purge_error_message(thd, mysql_bin_log.purge_logs(search_file_name, 0, 1, - 1, NULL); + 1, NULL)); } @@ -998,7 +998,7 @@ int change_master(THD* thd, MASTER_INFO* mi) mi->rli.group_master_log_pos = mi->master_log_pos; DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); /* If changing RELAY_LOG_FILE or RELAY_LOG_POS, this will be nonsense: */ - mi->rli.master_log_pos = mi->master_log_pos; + mi->rli.group_master_log_pos= mi->master_log_pos; strmake(mi->rli.group_master_log_name,mi->master_log_name, sizeof(mi->rli.group_master_log_name)-1); if (!mi->rli.group_master_log_name[0]) // uninitialized case @@ -1210,7 +1210,7 @@ int show_binlogs(THD* thd) if (!mysql_bin_log.is_open()) { //TODO: Replace with ER() error message - send_error(net, 0, "You are not using binary logging"); + send_error(thd, 0, "You are not using binary logging"); return 1; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index f3631263735..a40dcc42183 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -67,9 +67,9 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) TABLE_LIST *table_list; udf_func *udf; LEX_USER *lex_user; - sys_var *variable; + struct sys_var_with_base variable; Key::Keytype key_type; - enum ha_key_alg key_alg; + enum ha_key_alg key_alg; enum db_type db_type; enum row_type row_type; enum ha_rkey_function ha_rkey_mode; @@ -879,7 +879,7 @@ create: lex->name=0; } create2 - { Lex->select= &Lex->select_lex; } + { Lex->current_select= &Lex->select_lex; } | CREATE opt_unique_or_fulltext INDEX ident key_alg ON table_ident { LEX *lex=Lex; @@ -942,15 +942,15 @@ create2: create2a: field_list ')' opt_create_table_options create3 {} - | create_select ')' { Select->braces= 1;} union_opt {} + | create_select ')' { Select->set_braces(1);} union_opt {} ; create3: /* empty */ {} | opt_duplicate opt_as create_select - { Select->braces= 0;} opt_union {} + { Select->set_braces(0);} union_clause {} | opt_duplicate opt_as '(' create_select ')' - { Select->braces= 1;} union_opt {} + { Select->set_braces(1);} union_opt {} ; create_select: @@ -962,7 +962,7 @@ create_select: lex->sql_command= SQLCOM_INSERT_SELECT; else if (lex->sql_command == SQLCOM_REPLACE) lex->sql_command= SQLCOM_REPLACE_SELECT; - lex->select->table_list.save_and_clear(&lex->save_list); + lex->current_select->select_lex()->table_list.save_and_clear(&lex->save_list); mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST; } @@ -971,7 +971,7 @@ create_select: Select->parsing_place= SELECT_LEX_NODE::NO_MATTER; } opt_select_from - { Lex->select->table_list.push_front(&Lex->save_list); } + { Lex->current_select->select_lex()->table_list.push_front(&Lex->save_list); } ; opt_as: @@ -3434,7 +3434,7 @@ insert: opt_ignore insert2 { Select->set_lock_for_tables($3); - Lex->select= &Lex->select_lex; + Lex->current_select= &Lex->select_lex; } insert_field_spec opt_insert_update {} @@ -3451,7 +3451,7 @@ replace: replace_lock_option insert2 { Select->set_lock_for_tables($3); - Lex->select= &Lex->select_lex; + Lex->current_select= &Lex->select_lex; } insert_field_spec {} @@ -3507,8 +3507,8 @@ fields: insert_values: VALUES values_list {} | VALUE_SYM values_list {} - | create_select { Select->braces= 0;} opt_union {} - | '(' create_select ')' { Select->braces= 1;} union_opt {} + | create_select { Select->set_braces(0);} union_clause {} + | '(' create_select ')' { Select->set_braces(1);} union_opt {} ; values_list: @@ -4266,17 +4266,11 @@ IDENT_sys: IDENT { THD *thd= YYTHD; - if (my_charset_same(thd->charset(),system_charset_info)) - { - $$=$1; - } + if (thd->charset_is_system_charset) + $$= $1; else - { - String ident; - ident.copy($1.str,$1.length,thd->charset(),system_charset_info); - $$.str= thd->strmake(ident.ptr(),ident.length()); - $$.length= ident.length(); - } + thd->convert_string(&$$, system_charset_info, + $1.str, $1.length, thd->charset()); } ; @@ -4284,17 +4278,11 @@ TEXT_STRING_sys: TEXT_STRING { THD *thd= YYTHD; - if (my_charset_same(thd->charset(),system_charset_info)) - { - $$=$1; - } + if (thd->charset_is_system_charset) + $$= $1; else - { - String ident; - ident.copy($1.str,$1.length,thd->charset(),system_charset_info); - $$.str= thd->strmake(ident.ptr(),ident.length()); - $$.length= ident.length(); - } + thd->convert_string(&$$, system_charset_info, + $1.str, $1.length, thd->charset()); } ; @@ -4302,17 +4290,11 @@ TEXT_STRING_literal: TEXT_STRING { THD *thd= YYTHD; - if (my_charset_same(thd->charset(),thd->variables.collation_connection)) - { - $$=$1; - } + if (thd->charset_is_collation_connection) + $$= $1; else - { - String ident; - ident.copy($1.str,$1.length,thd->charset(),thd->variables.collation_connection); - $$.str= thd->strmake(ident.ptr(),ident.length()); - $$.length= ident.length(); - } + thd->convert_string(&$$, thd->variables.collation_connection, + $1.str, $1.length, thd->charset()); } ; @@ -4321,9 +4303,9 @@ ident: IDENT_sys { $$=$1; } | keyword { - LEX *lex= Lex; - $$.str= lex->thd->strmake($1.str,$1.length); - $$.length=$1.length; + THD *thd= YYTHD; + $$.str= thd->strmake($1.str, $1.length); + $$.length= $1.length; } ; @@ -4590,18 +4572,24 @@ option_value: | internal_variable_name equal set_expr_or_default { LEX *lex=Lex; - lex->var_list.push_back(new set_var(lex->option_type, $1, $3)); + lex->var_list.push_back(new set_var(lex->option_type, $1.var, + &$1.base_name, $3)); } | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default { LEX *lex=Lex; - lex->var_list.push_back(new set_var((enum_var_type) $3, $4, $6)); + lex->var_list.push_back(new set_var((enum_var_type) $3, $4.var, + &$4.base_name, $6)); } | TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types { LEX *lex=Lex; + LEX_STRING tmp; + tmp.str=0; + tmp.length=0; lex->var_list.push_back(new set_var(lex->option_type, find_sys_var("tx_isolation"), + &tmp, new Item_int((int32) $4))); } | charset old_or_new_charset_name_or_default @@ -4646,7 +4634,9 @@ internal_variable_name: sys_var *tmp=find_sys_var($1.str, $1.length); if (!tmp) YYABORT; - $$=tmp; + $$.var= tmp; + $$.base_name.str=0; + $$.base_name.length=0; } | ident '.' ident { @@ -4655,8 +4645,8 @@ internal_variable_name: YYABORT; if (!tmp->is_struct()) net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str); - tmp->base_name= $1; - $$=tmp; + $$.var= tmp; + $$.base_name= $1; } | DEFAULT '.' ident { @@ -4665,9 +4655,9 @@ internal_variable_name: YYABORT; if (!tmp->is_struct()) net_printf(YYTHD, ER_VARIABLE_IS_NOT_STRUCT, $3.str); - tmp->base_name.str= (char*) "default"; - tmp->base_name.length= 7; - $$=tmp; + $$.var= tmp; + $$.base_name.str= (char*) "default"; + $$.base_name.length= 7; } ; diff --git a/strings/ctype-latin1.c b/strings/ctype-latin1.c index b0c60e2e3eb..cf21f129664 100644 --- a/strings/ctype-latin1.c +++ b/strings/ctype-latin1.c @@ -262,13 +262,42 @@ static uchar sort_order_latin1_de[] = { 68, 78, 79, 79, 79, 79,214,247,216, 85, 85, 85,220, 89,222, 89 }; -#define L1_AE 196 -#define L1_ae 228 -#define L1_OE 214 -#define L1_oe 246 -#define L1_UE 220 -#define L1_ue 252 -#define L1_ss 223 + +/* + same as sort_order_latin_de, but maps ALL accented chars to unaccented ones +*/ + +uchar combo1map[]={ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127, + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, + 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, + 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, + 65, 65, 65, 65, 65, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73, + 68, 78, 79, 79, 79, 79, 79,215,216, 85, 85, 85, 85, 89,222, 83, + 65, 65, 65, 65, 65, 65, 92, 67, 69, 69, 69, 69, 73, 73, 73, 73, + 68, 78, 79, 79, 79, 79, 79,247,216, 85, 85, 85, 85, 89,222, 89 +}; + +uchar combo2map[]={ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,69, 0, 0,83, 0, 0, 0, 0,69, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,69, 0, 0, 0, 0, 0,69, 0, 0, 0, 0 +}; /* @@ -285,101 +314,48 @@ static uchar sort_order_latin1_de[] = { */ -#define CHECK_S1_COMBO(ch1, ch2, str1, str1_end, res_if_str1_smaller, str2, fst, snd, accent) \ - /* Invariant: ch1 == fst == sort_order_latin1_de[accent] && ch1 != ch2 */ \ - if (ch2 != accent) \ - { \ - ch1= fst; \ - goto normal; \ - } \ - if (str1 == str1_end) \ - return res_if_str1_smaller; \ - { \ - int diff = (int) sort_order_latin1_de[*str1] - snd; \ - if (diff) \ - return diff*(-(res_if_str1_smaller)); \ - /* They are equal (e.g., "Ae" == 'ä') */ \ - str1++; \ - } - - static int my_strnncoll_latin1_de(CHARSET_INFO *cs __attribute__((unused)), - const uchar * s1, uint len1, - const uchar * s2, uint len2) + const uchar *s1, uint len1, + const uchar *s2, uint len2) { const uchar *e1 = s1 + len1; const uchar *e2 = s2 + len2; + uchar c1, c12=0, c2, c22=0; - while (s1 < e1 && s2 < e2) + while ((s1 < e1 || c12) && (s2 < e2 || c22)) { - /* - Because sort_order_latin1_de doesn't convert 'Ä', Ü or ß we - can use it here. - */ - uchar c1 = sort_order_latin1_de[*s1++]; - uchar c2 = sort_order_latin1_de[*s2++]; - if (c1 != c2) + if (c12) { - switch (c1) { - case 'A': - CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'A', 'E', L1_AE); - break; - case 'O': - CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'O', 'E', L1_OE); - break; - case 'U': - CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'U', 'E', L1_UE); - break; - case 'S': - CHECK_S1_COMBO(c1, c2, s1, e1, -1, s2, 'S', 'S', L1_ss); - break; - case L1_AE: - CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'A', 'E', 'A'); - break; - case L1_OE: - CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'O', 'E', 'O'); - break; - case L1_UE: - CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'U', 'E', 'U'); - break; - case L1_ss: - CHECK_S1_COMBO(c1, c2, s2, e2, 1, s1, 'S', 'S', 'S'); - break; - default: - /* - Handle the case where 'c2' is a special character - If this is true, we know that c1 can't match this character. - */ - normal: - switch (c2) { - case L1_AE: - return (int) c1 - (int) 'A'; - case L1_OE: - return (int) c1 - (int) 'O'; - case L1_UE: - return (int) c1 - (int) 'U'; - case L1_ss: - return (int) c1 - (int) 'S'; - default: - { - int diff= (int) c1 - (int) c2; - if (diff) - return diff; - } - break; - } - } + c1=c12; c12=0; } + else + { + c12=combo2map[*s1]; + c1=combo1map[*s1++]; + } + if (c22) + { + c2=c22; c22=0; + } + else + { + c22=combo2map[*s2]; + c2=combo1map[*s2++]; + } + if (c1 != c2) return (int)c1 - (int)c2; } - /* A simple test of string lengths won't work -- we test to see - * which string ran out first */ - return s1 < e1 ? 1 : s2 < e2 ? -1 : 0; + + /* + A simple test of string lengths won't work -- we test to see + which string ran out first + */ + return (s1 < e1 || c12) ? 1 : (s2 < e2 || c22) ? -1 : 0; } -static -int my_strnncollsp_latin1_de(CHARSET_INFO * cs, - const uchar *s, uint slen, - const uchar *t, uint tlen) + +static int my_strnncollsp_latin1_de(CHARSET_INFO *cs, + const uchar *s, uint slen, + const uchar *t, uint tlen) { for ( ; slen && my_isspace(cs, s[slen-1]) ; slen--); for ( ; tlen && my_isspace(cs, t[tlen-1]) ; tlen--); @@ -388,99 +364,76 @@ int my_strnncollsp_latin1_de(CHARSET_INFO * cs, static int my_strnxfrm_latin1_de(CHARSET_INFO *cs __attribute__((unused)), - uchar * dest, uint len, - const uchar * src, uint srclen) + uchar * dest, uint len, + const uchar * src, uint srclen) { const uchar *dest_orig = dest; const uchar *de = dest + len; const uchar *se = src + srclen; - while (src < se && dest < de) + for ( ; src < se && dest < de ; src++) { - uchar chr=sort_order_latin1_de[*src]; - switch (chr) { - case L1_AE: - *dest++ = 'A'; - if (dest < de) - *dest++ = 'E'; - break; - case L1_OE: - *dest++ = 'O'; - if (dest < de) - *dest++ = 'E'; - break; - case L1_UE: - *dest++ = 'U'; - if (dest < de) - *dest++ = 'E'; - break; - case L1_ss: - *dest++ = 'S'; - if (dest < de) - *dest++ = 'S'; - break; - default: - *dest++= chr; - break; - } - ++src; + uchar chr=combo1map[*src]; + *dest++=chr; + if ((chr=combo2map[*src]) && dest < de) + *dest++=chr; } - return dest - dest_orig; + return (int) (dest - dest_orig); } static MY_COLLATION_HANDLER my_collation_german2_ci_handler= { - my_strnncoll_latin1_de, - my_strnncollsp_latin1_de, - my_strnxfrm_latin1_de, - my_like_range_simple, - my_wildcmp_8bit, - my_strcasecmp_8bit, - my_hash_sort_simple + my_strnncoll_latin1_de, + my_strnncollsp_latin1_de, + my_strnxfrm_latin1_de, + my_like_range_simple, + my_wildcmp_8bit, + my_strcasecmp_8bit, + my_hash_sort_simple }; CHARSET_INFO my_charset_latin1_german2_ci= { - 31,0,0, /* number */ - MY_CS_COMPILED|MY_CS_STRNXFRM, /* state */ - "latin1", /* cs name */ - "latin1_german2_ci", /* name */ - "", /* comment */ - ctype_latin1, - to_lower_latin1, - to_upper_latin1, - sort_order_latin1_de, - latin1_uni, /* tab_to_uni */ - NULL, /* tab_from_uni */ - "","", - 2, /* strxfrm_multiply */ - 1, /* mbmaxlen */ - 0, - &my_charset_handler, - &my_collation_german2_ci_handler + 31,0,0, /* number */ + MY_CS_COMPILED|MY_CS_STRNXFRM, /* state */ + "latin1", /* cs name */ + "latin1_german2_ci", /* name */ + "", /* comment */ + ctype_latin1, + to_lower_latin1, + to_upper_latin1, + sort_order_latin1_de, + latin1_uni, /* tab_to_uni */ + NULL, /* tab_from_uni */ + "","", + 2, /* strxfrm_multiply */ + 1, /* mbmaxlen */ + 0, + &my_charset_handler, + &my_collation_german2_ci_handler }; CHARSET_INFO my_charset_latin1_bin= { - 47,0,0, /* number */ - MY_CS_COMPILED|MY_CS_BINSORT, /* state */ - "latin1", /* cs name */ - "latin1_bin", /* name */ - "", /* comment */ - ctype_latin1, - to_lower_latin1, - to_upper_latin1, - sort_order_latin1_de, - latin1_uni, /* tab_to_uni */ - NULL, /* tab_from_uni */ - "", - "", - 0, /* strxfrm_multiply */ - 1, /* mbmaxlen */ - 0, - &my_charset_handler, - &my_collation_bin_handler + 47,0,0, /* number */ + MY_CS_COMPILED|MY_CS_BINSORT, /* state */ + "latin1", /* cs name */ + "latin1_bin", /* name */ + "", /* comment */ + ctype_latin1, + to_lower_latin1, + to_upper_latin1, + sort_order_latin1_de, + latin1_uni, /* tab_to_uni */ + NULL, /* tab_from_uni */ + "", + "", + 0, /* strxfrm_multiply */ + 1, /* mbmaxlen */ + 0, + &my_charset_handler, + &my_collation_bin_handler }; From ba77af7321d7ab7414cd82906f3172703ee0f237 Mon Sep 17 00:00:00 2001 From: "ram@mysql.r18.ru" <> Date: Tue, 19 Aug 2003 12:49:47 +0500 Subject: [PATCH 236/237] Removed idle MY_LEX_SIGNED_NUMBER --- include/m_ctype.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/m_ctype.h b/include/m_ctype.h index f6b5a1ca44f..4ae6734a48c 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -79,7 +79,7 @@ enum my_lex_states { MY_LEX_START, MY_LEX_CHAR, MY_LEX_IDENT, MY_LEX_IDENT_SEP, MY_LEX_IDENT_START, - MY_LEX_FOUND_IDENT, MY_LEX_SIGNED_NUMBER, MY_LEX_REAL, MY_LEX_HEX_NUMBER, + MY_LEX_FOUND_IDENT, MY_LEX_REAL, MY_LEX_HEX_NUMBER, MY_LEX_CMP_OP, MY_LEX_LONG_CMP_OP, MY_LEX_STRING, MY_LEX_COMMENT, MY_LEX_END, MY_LEX_OPERATOR_OR_IDENT, MY_LEX_NUMBER_IDENT, MY_LEX_INT_OR_REAL, MY_LEX_REAL_OR_POINT, MY_LEX_BOOL, MY_LEX_EOL, MY_LEX_ESCAPE, From eb6458cb18ec31e2be09cf6555a24ef3545c4fa0 Mon Sep 17 00:00:00 2001 From: "monty@mashka.mysql.fi" <> Date: Tue, 19 Aug 2003 16:00:12 +0300 Subject: [PATCH 237/237] After merge fixes + bugs from last merge --- mysql-test/mysql-test-run.sh | 6 +++--- mysql-test/t/union.test | 2 +- sql/item.cc | 2 +- sql/log_event.cc | 2 -- sql/protocol.h | 2 +- sql/set_var.cc | 4 +++- sql/slave.cc | 8 +++++--- sql/sql_base.cc | 2 ++ sql/sql_class.cc | 4 +--- sql/sql_parse.cc | 37 +++++++++++++++++------------------- sql/table.cc | 31 ++++++++++++++++-------------- 11 files changed, 51 insertions(+), 49 deletions(-) diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 8800055a3bb..874abdc0c86 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -344,8 +344,8 @@ while test $# -gt 0; do ;; --valgrind) VALGRIND="valgrind --alignment=8 --leak-check=yes --num-callers=16" - EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc" - EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc" + EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb" + EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb" SLEEP_TIME_AFTER_RESTART=10 SLEEP_TIME_FOR_DELETE=60 USE_RUNNING_SERVER="" @@ -998,7 +998,7 @@ start_slave() if [ x$DO_DDD = x1 ] then - $ECHO "set args $master_args" > $GDB_SLAVE_INIT + $ECHO "set args $slave_args" > $GDB_SLAVE_INIT manager_launch $slave_ident ddd -display $DISPLAY --debugger \ "gdb -x $GDB_SLAVE_INIT" $SLAVE_MYSQLD elif [ x$DO_GDB = x1 ] diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index c5aa725a459..3506c713907 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -23,7 +23,7 @@ select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 g (select a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 4; (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1); (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc; ---error 1248 +--error 1249 (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b; explain (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc; (select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2; diff --git a/sql/item.cc b/sql/item.cc index 17b0519b61c..060aa2b63a1 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -50,7 +50,7 @@ Item::Item(): next= thd->free_list; // Put in free list thd->free_list= this; /* - Item constructor can be called during execution other tnen SQL_COM + Item constructor can be called during execution other then SQL_COM command => we should check thd->lex.current_select on zero (thd->lex can be uninitialised) */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 3b04baf7ae7..8a52ad9ebca 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -911,7 +911,6 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); - thd->current_tablenr = 0; thd->query_length= q_len; VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query = (char*)query; @@ -1617,7 +1616,6 @@ int Load_log_event::exec_event(NET* net, struct st_relay_log_info* rli, if (db_ok(thd->db, replicate_do_db, replicate_ignore_db)) { thd->set_time((time_t)when); - thd->current_tablenr = 0; VOID(pthread_mutex_lock(&LOCK_thread_count)); thd->query_id = query_id++; VOID(pthread_mutex_unlock(&LOCK_thread_count)); diff --git a/sql/protocol.h b/sql/protocol.h index ffd61b3e848..05aee12d3d9 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -61,7 +61,7 @@ public: inline bool store(ulonglong from) { return store_longlong((longlong) from, 1); } inline bool store(String *str) - { return store(str->c_ptr(),str->length(),str->charset()); } + { return store((char*) str->ptr(), str->length(), str->charset()); } virtual bool prepare_for_send(List *item_list) { diff --git a/sql/set_var.cc b/sql/set_var.cc index 499eed132a7..91583759c70 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -823,7 +823,7 @@ void fix_max_binlog_size(THD *thd, enum_var_type type) DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", max_binlog_size, max_relay_log_size)); mysql_bin_log.set_max_size(max_binlog_size); -#ifdef REPLICATION +#ifdef HAVE_REPLICATION if (!max_relay_log_size) active_mi->rli.relay_log.set_max_size(max_binlog_size); #endif @@ -835,8 +835,10 @@ void fix_max_relay_log_size(THD *thd, enum_var_type type) DBUG_ENTER("fix_max_relay_log_size"); DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu", max_binlog_size, max_relay_log_size)); +#ifdef HAVE_REPLICATION active_mi->rli.relay_log.set_max_size(max_relay_log_size ? max_relay_log_size: max_binlog_size); +#endif DBUG_VOID_RETURN; } diff --git a/sql/slave.cc b/sql/slave.cc index 16d493f1667..d45cf1aa8b9 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1137,7 +1137,6 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db, return 1; } thd->query= query; - thd->current_tablenr = 0; thd->query_error = 0; thd->net.no_send_ok = 1; @@ -1811,7 +1810,8 @@ int show_master_info(THD* thd, MASTER_INFO* mi) field_list.push_back(new Item_empty_string("Replicate_do_table", 20)); field_list.push_back(new Item_empty_string("Replicate_ignore_table", 23)); field_list.push_back(new Item_empty_string("Replicate_wild_do_table", 24)); - field_list.push_back(new Item_empty_string("Replicate_wild_ignore_table", 28)); + field_list.push_back(new Item_empty_string("Replicate_wild_ignore_table", + 28)); field_list.push_back(new Item_return_int("Last_errno", 4, MYSQL_TYPE_LONG)); field_list.push_back(new Item_empty_string("Last_error", 20)); field_list.push_back(new Item_return_int("Skip_counter", 10, @@ -1838,7 +1838,8 @@ int show_master_info(THD* thd, MASTER_INFO* mi) protocol->store(mi->master_log_name, &my_charset_bin); protocol->store((ulonglong) mi->master_log_pos); protocol->store(mi->rli.group_relay_log_name + - dirname_length(mi->rli.group_relay_log_name), &my_charset_bin); + dirname_length(mi->rli.group_relay_log_name), + &my_charset_bin); protocol->store((ulonglong) mi->rli.group_relay_log_pos); protocol->store(mi->rli.group_master_log_name, &my_charset_bin); protocol->store(mi->slave_running ? "Yes":"No", &my_charset_bin); @@ -2384,6 +2385,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) thd->server_id = ev->server_id; // use the original server id for logging thd->set_time(); // time the query + thd->lex.current_select= 0; if (!ev->when) ev->when = time(NULL); ev->thd = thd; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index fd0768d6ae7..b6c84be5363 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1355,6 +1355,7 @@ int open_tables(THD *thd,TABLE_LIST *start) int result=0; DBUG_ENTER("open_tables"); + thd->current_tablenr= 0; restart: thd->proc_info="Opening tables"; for (tables=start ; tables ; tables=tables->next) @@ -1473,6 +1474,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type) DBUG_ENTER("open_ltable"); thd->proc_info="Opening table"; + thd->current_tablenr= 0; while (!(table=open_table(thd,table_list->db, table_list->real_name,table_list->alias, &refresh)) && refresh) ; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c29e7ca2213..763408dc5c2 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -96,7 +96,6 @@ THD::THD():user_time(0), is_fatal_error(0), query_error= tmp_table_used= 0; next_insert_id=last_insert_id=0; open_tables= temporary_tables= handler_tables= derived_tables= 0; - current_tablenr=0; handler_items=0; tmp_table=0; lock=locked_tables=0; @@ -161,8 +160,6 @@ THD::THD():user_time(0), is_fatal_error(0), else bzero((char*) &user_var_events, sizeof(user_var_events)); - - /* Prepared statements */ last_prepared_stmt= 0; init_tree(&prepared_statements, 0, 0, sizeof(PREP_STMT), @@ -218,6 +215,7 @@ void THD::init(void) warn_list.empty(); bzero((char*) warn_count, sizeof(warn_count)); total_warn_count= 0; + update_charset(); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 694d1148867..fad388dca7f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -982,7 +982,6 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) buff[length-1] == ';')) length--; buff[length]=0; - thd->current_tablenr=0; thd->query_length=length; thd->query= thd->memdup_w_gap(buff, length+1, thd->db_length+1); thd->query[length] = '\0'; @@ -1085,7 +1084,6 @@ bool do_command(THD *thd) DBUG_ENTER("do_command"); net= &thd->net; - thd->current_tablenr=0; /* indicator of uninitialized lex => normal flow of errors handling (see my_message_sql) @@ -1172,21 +1170,20 @@ bool dispatch_command(enum enum_server_command command, THD *thd, } #endif case COM_TABLE_DUMP: - { - statistic_increment(com_other, &LOCK_status); - slow_command = TRUE; - uint db_len = *(uchar*)packet; - uint tbl_len = *(uchar*)(packet + db_len + 1); - char* db = thd->alloc(db_len + tbl_len + 2); - memcpy(db, packet + 1, db_len); - char* tbl_name = db + db_len; - *tbl_name++ = 0; - memcpy(tbl_name, packet + db_len + 2, tbl_len); - tbl_name[tbl_len] = 0; - if (mysql_table_dump(thd, db, tbl_name, -1)) - send_error(thd); // dump to NET - break; - } + { + char *db, *tbl_name; + uint db_len= *(uchar*) packet; + uint tbl_len= *(uchar*) (packet + db_len + 1); + + statistic_increment(com_other, &LOCK_status); + slow_command= TRUE; + db= thd->alloc(db_len + tbl_len + 2); + tbl_name= strmake(db, packet + 1, db_len)+1; + strmake(tbl_name, packet + db_len + 2, tbl_len); + if (mysql_table_dump(thd, db, tbl_name, -1)) + send_error(thd); // dump to NET + break; + } #ifndef EMBEDDED_LIBRARY case COM_CHANGE_USER: { @@ -1703,9 +1700,9 @@ mysql_execute_command(THD *thd) } #ifndef TO_BE_DELETED /* - This is a workaround to deal with the shortcoming in 3.23.44-3.23.46 - masters in RELEASE_LOCK() logging. We re-write SELECT RELEASE_LOCK() - as DO RELEASE_LOCK() + This is a workaround to deal with the shortcoming in 3.23.44-3.23.46 + masters in RELEASE_LOCK() logging. We re-write SELECT RELEASE_LOCK() + as DO RELEASE_LOCK() */ if (lex->sql_command == SQLCOM_SELECT) { diff --git a/sql/table.cc b/sql/table.cc index a76bdc84690..9d12de1f6c7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1173,23 +1173,25 @@ rename_file_ext(const char * from,const char * to,const char * ext) res result String RETURN VALUES - true string is empty - false all ok + 1 string is empty + 0 all ok */ bool get_field(MEM_ROOT *mem, Field *field, String *res) { - char buff[MAX_FIELD_WIDTH]; + char buff[MAX_FIELD_WIDTH], *to; String str(buff,sizeof(buff),&my_charset_bin); + uint length; + field->val_str(&str,&str); - uint length=str.length(); - if (!length) - return true; - char *to= strmake_root(mem, str.ptr(), length); - res->set(to,length,((Field_str*)field)->charset()); - return false; + if (!(length= str.length())) + return 1; + to= strmake_root(mem, str.ptr(), length); + res->set(to, length, ((Field_str*)field)->charset()); + return 0; } + /* Allocate string field in MEM_ROOT and return it as NULL-terminated string @@ -1205,14 +1207,15 @@ bool get_field(MEM_ROOT *mem, Field *field, String *res) char *get_field(MEM_ROOT *mem, Field *field) { - char buff[MAX_FIELD_WIDTH]; + char buff[MAX_FIELD_WIDTH], *to; String str(buff,sizeof(buff),&my_charset_bin); + uint length; + field->val_str(&str,&str); - uint length=str.length(); - if (!length) + if (!(length= str.length())) return NullS; - char *to= (char*) alloc_root(mem,length+1); - memcpy(to,str.ptr(),(uint) length); + to= (char*) alloc_root(mem,length+1); + memcpy(to, str.ptr(), (uint) length); to[length]=0; return to; }