diff --git a/client/mysql.cc b/client/mysql.cc index 8cbaf241bec..d3885645124 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -371,10 +371,16 @@ int main(int argc,char *argv[]) !(status.line_buff=batch_readline_init(max_allowed_packet+512,stdin))) { free_defaults(defaults_argv); + my_end(0); + exit(1); + } + if (mysql_server_init(0, NULL, (char**) server_default_groups)) + { + free_defaults(defaults_argv); + my_end(0); exit(1); } glob_buffer.realloc(512); - mysql_server_init(0, NULL, (char**) server_default_groups); completion_hash_init(&ht, 128); init_alloc_root(&hash_mem_root, 16384, 0); bzero((char*) &mysql, sizeof(mysql)); diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h index 1608f4ed4ad..d4316dff63f 100644 --- a/libmysqld/embedded_priv.h +++ b/libmysqld/embedded_priv.h @@ -28,5 +28,6 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db); void *create_embedded_thd(int client_flag, char *db); int check_embedded_connection(MYSQL *mysql); void free_old_query(MYSQL *mysql); +void embedded_get_error(MYSQL *mysql); extern MYSQL_METHODS embedded_methods; C_MODE_END diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 09b03e38f2e..2bbca220db9 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -42,6 +42,22 @@ C_MODE_START #include "errmsg.h" #include +void embedded_get_error(MYSQL *mysql) +{ + THD *thd=(THD *) mysql->thd; + NET *net= &mysql->net; + if ((net->last_errno= thd->net.last_errno)) + { + memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error)); + memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate)); + } + else + { + net->last_error[0]= 0; + strmov(net->sqlstate, not_error_sqlstate); + } +} + static my_bool emb_advanced_command(MYSQL *mysql, enum enum_server_command command, const char *header, ulong header_length, @@ -86,16 +102,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command, if (!skip_check) result= thd->net.last_errno ? -1 : 0; - if ((net->last_errno= thd->net.last_errno)) - { - memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error)); - memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate)); - } - else - { - net->last_error[0]= 0; - strmov(net->sqlstate, not_error_sqlstate); - } + embedded_get_error(mysql); mysql->server_status= thd->server_status; mysql->warning_count= ((THD*)mysql->thd)->total_warn_count; return result; @@ -239,6 +246,7 @@ static void emb_free_embedded_thd(MYSQL *mysql) free_rows(thd->data); thread_count--; delete thd; + mysql->thd=0; } static const char * emb_read_statistics(MYSQL *mysql) @@ -498,8 +506,7 @@ int check_embedded_connection(MYSQL *mysql) thd->host= (char*)my_localhost; thd->host_or_ip= thd->host; thd->user= my_strdup(mysql->user, MYF(0)); - check_user(thd, COM_CONNECT, NULL, 0, thd->db, true); - return 0; + return check_user(thd, COM_CONNECT, NULL, 0, thd->db, true); } #else diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c index 95f745aef5f..db9e828369d 100644 --- a/libmysqld/libmysqld.c +++ b/libmysqld/libmysqld.c @@ -232,6 +232,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, DBUG_RETURN(mysql); error: + embedded_get_error(mysql); DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno, mysql->net.last_error)); { diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 981ef23c779..83d042cd279 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -1595,3 +1595,26 @@ t2 CREATE TABLE `t2` ( CONSTRAINT `t2_ibfk_2` FOREIGN KEY (`b`) REFERENCES `t1` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t2, t1; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 24 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 0 +create table t1 (a int) engine=innodb; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 25 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +begin; +delete from t1; +commit; +show status like "binlog_cache_use"; +Variable_name Value +Binlog_cache_use 26 +show status like "binlog_cache_disk_use"; +Variable_name Value +Binlog_cache_disk_use 1 +drop table t1; diff --git a/mysql-test/r/rpl_relayrotate.result b/mysql-test/r/rpl_relayrotate.result index 96ec06a69aa..bf9bbbb9b93 100644 --- a/mysql-test/r/rpl_relayrotate.result +++ b/mysql-test/r/rpl_relayrotate.result @@ -16,19 +16,4 @@ master_pos_wait('master-bin.001',3000)>=0 select * from t1 where a=8000; a 8000 -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 1 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 1 -begin; -delete from t1; -commit; -show status like "binlog_cache_use"; -Variable_name Value -Binlog_cache_use 2 -show status like "binlog_cache_disk_use"; -Variable_name Value -Binlog_cache_disk_use 1 drop table t1; diff --git a/mysql-test/t/rpl_relayrotate-master.opt b/mysql-test/t/innodb-master.opt similarity index 100% rename from mysql-test/t/rpl_relayrotate-master.opt rename to mysql-test/t/innodb-master.opt diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 47e82db2dc4..e0cc96ccb32 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1106,4 +1106,37 @@ show create table t2; drop table t2, t1; +# +# Let us test binlog_cache_use and binlog_cache_disk_use status vars. +# Actually this test has nothing to do with innodb per se, it just requires +# transactional table. +# +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; +create table t1 (a int) engine=innodb; + +# Now we are going to create transaction which is long enough so its +# transaction binlog will be flushed to disk... +let $1=2000; +disable_query_log; +begin; +while ($1) +{ + eval insert into t1 values( $1 ); + dec $1; +} +commit; +enable_query_log; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +# Transaction which should not be flushed to disk and so should not +# increase binlog_cache_disk_use. +begin; +delete from t1; +commit; +show status like "binlog_cache_use"; +show status like "binlog_cache_disk_use"; + +drop table t1; diff --git a/mysql-test/t/rpl_relayrotate.test b/mysql-test/t/rpl_relayrotate.test index ca3bff81608..46e6f1bd157 100644 --- a/mysql-test/t/rpl_relayrotate.test +++ b/mysql-test/t/rpl_relayrotate.test @@ -60,22 +60,6 @@ select * from t1 where a=8000; connection master; -# binlog_cache_use and binlog_cache_disk_use status vars test -# This test uses the previous test. Namely, it needs the long -# transaction that adds 8000 lines to the t1 table. - -show status like "binlog_cache_use"; -show status like "binlog_cache_disk_use"; - -# transaction which should not be flushed to disk and so should not -# increase binlog_cache_disk_use -begin; -delete from t1; -commit; - -show status like "binlog_cache_use"; -show status like "binlog_cache_disk_use"; - # The following DROP is a very important cleaning task: # imagine the next test is run with --skip-innodb: it will do # DROP TABLE IF EXISTS t1; but this will delete the frm and leave diff --git a/sql/handler.cc b/sql/handler.cc index 9acd55db0b1..bc86241bd00 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -743,7 +743,7 @@ int ha_delete_table(enum db_type table_type, const char *path) { /* Ensure that table handler get path in lower case */ strmov(tmp_path, path); - my_casedn_str(system_charset_info, tmp_path); + my_casedn_str(files_charset_info, tmp_path); path= tmp_path; } int error=file->delete_table(path); @@ -1247,7 +1247,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info, { /* Ensure that handler gets name in lower case */ strmov(name_buff, name); - my_casedn_str(system_charset_info, name_buff); + my_casedn_str(files_charset_info, name_buff); name= name_buff; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fbd47d4954d..25ff4c5676b 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -953,7 +953,7 @@ ulong acl_get(const char *host, const char *ip, end=strmov((tmp_db=strmov(strmov(key, ip ? ip : "")+1,user)+1),db); if (lower_case_table_names) { - my_casedn_str(&my_charset_latin1, tmp_db); + my_casedn_str(files_charset_info, tmp_db); db=tmp_db; } key_length=(uint) (end-key); @@ -1733,8 +1733,8 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u, tname= strdup_root(&memex,t); if (lower_case_table_names) { - my_casedn_str(&my_charset_latin1, db); - my_casedn_str(&my_charset_latin1, tname); + my_casedn_str(files_charset_info, db); + my_casedn_str(files_charset_info, tname); } key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3; hash_key = (char*) alloc_root(&memex,key_length); @@ -1768,8 +1768,8 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) } if (lower_case_table_names) { - my_casedn_str(&my_charset_latin1, db); - my_casedn_str(&my_charset_latin1, tname); + my_casedn_str(files_charset_info, db); + my_casedn_str(files_charset_info, tname); } key_length = ((uint) strlen(db) + (uint) strlen(user) + (uint) strlen(tname) + 3); @@ -2416,7 +2416,7 @@ int mysql_grant(THD *thd, const char *db, List &list, if (lower_case_table_names && db) { strmov(tmp_db,db); - my_casedn_str(&my_charset_latin1, tmp_db); + my_casedn_str(files_charset_info, tmp_db); db=tmp_db; } diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index d7d4219c7fd..b9fe61ac48a 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -1512,13 +1512,28 @@ ulong Query_cache::init_cache() VOID(hash_init(&queries, &my_charset_bin, def_query_hash_size, 0, 0, query_cache_query_get_key, 0, 0)); #ifndef FN_NO_CASE_SENCE + /* + If lower_case_table_names!=0 then db and table names are already + converted to lower case and we can use binary collation for their + comparison (no matter if file system case sensitive or not). + If we have case-sensitive file system (like on most Unixes) and + lower_case_table_names == 0 then we should distinguish my_table + and MY_TABLE cases and so again can use binary collation. + */ VOID(hash_init(&tables, &my_charset_bin, def_table_hash_size, 0, 0, query_cache_table_get_key, 0, 0)); #else - // windows, OS/2 or other case insensitive file names work around + /* + On windows, OS/2, MacOS X with HFS+ or any other case insensitive + file system if lower_case_table_names!=0 we have same situation as + in previous case, but if lower_case_table_names==0 then we should + not distinguish cases (to be compatible in behavior with underlaying + file system) and so should use case insensitive collation for + comparison. + */ VOID(hash_init(&tables, lower_case_table_names ? &my_charset_bin : - system_charset_info, + files_charset_info, def_table_hash_size, 0, 0,query_cache_table_get_key, 0, 0)); #endif diff --git a/sql/sql_db.cc b/sql/sql_db.cc index bddaebdc0f2..39c8c00898d 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -366,7 +366,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) { /* Convert database to lower case */ strmov(tmp_db, db); - my_casedn_str(system_charset_info, tmp_db); + my_casedn_str(files_charset_info, tmp_db); db= tmp_db; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 80634c68ac7..4fb85d9bab7 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -422,7 +422,7 @@ mysql_find_files(THD *thd,List *files, const char *db,const char *path, { if (lower_case_table_names) { - if (wild_case_compare(system_charset_info,file->name,wild)) + if (wild_case_compare(files_charset_info, file->name, wild)) continue; } else if (wild_compare(file->name,wild,0)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e017bc7e6b5..383165824d7 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1395,11 +1395,11 @@ mysql_rename_table(enum db_type base, { /* Table handler expects to get all file names as lower case */ strmov(tmp_from, old_name); - my_casedn_str(system_charset_info, tmp_from); + my_casedn_str(files_charset_info, tmp_from); old_name= tmp_from; strmov(tmp_to, new_name); - my_casedn_str(system_charset_info, tmp_to); + my_casedn_str(files_charset_info, tmp_to); new_name= tmp_to; } my_snprintf(from, sizeof(from), "%s/%s/%s", @@ -2514,10 +2514,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { if (lower_case_table_names != 2) { - my_casedn_str(system_charset_info, new_name_buff); + my_casedn_str(files_charset_info, new_name_buff); new_alias= new_name; // Create lower case table name } - my_casedn_str(system_charset_info, new_name); + my_casedn_str(files_charset_info, new_name); } if (new_db == db && !my_strcasecmp(table_alias_charset, new_name_buff, table_name)) @@ -2880,7 +2880,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, current_pid, thd->thread_id); /* Safety fix for innodb */ if (lower_case_table_names) - my_casedn_str(system_charset_info, tmp_name); + my_casedn_str(files_charset_info, tmp_name); create_info->db_type=new_db_type; if (!create_info->comment) create_info->comment=table->comment;