From 2466cbc4793fd56e531d128225227ba05e019757 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Aug 2004 15:26:27 +0300 Subject: [PATCH 01/38] Fix for Bug#3759 The cause of the bug is that Item_func_in::fix_fields did not fully update its used_table_cache. This was the cause for not_null_tables in setup_conds() to be still 0 after the call not_null_tables= (*conds)->not_null_tables(); As a result the condition in setup_conds() if ( ... (table->table->map & not_null_tables) ...) failed, which was the cause for the ON expression not to be added to conds, and later the optimizer couldn't detect that it could apply the OUTER JOIN ==> JOIN optimization. sql/item_cmpfunc.h: Fix for Bug#3759 BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + sql/item_cmpfunc.h | 3 +++ 2 files changed, 4 insertions(+) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 698f7655b6e..ce1b4d16eb9 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -136,6 +136,7 @@ tim@sand.box tim@threads.polyesthetic.msg tim@white.box tim@work.mysql.com +timour@mysql.com tom@basil-firewall.home.com tonu@hundin.mysql.fi tonu@volk.internalnet diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 236ebb8d28b..a4f8118f21d 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -431,6 +431,9 @@ class Item_func_in :public Item_int_func { bool res= (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); with_sum_func= with_sum_func || item->with_sum_func; + used_tables_cache|= item->used_tables(); + not_null_tables_cache|= item->not_null_tables(); + const_item_cache&= item->const_item(); return res; } void fix_length_and_dec(); From 65a94e3470018a66d4b148c40fd7e5b91db229ed Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Aug 2004 18:14:29 +0300 Subject: [PATCH 02/38] added test for BUG#3759 --- mysql-test/r/select.result | 21 +++++++++++++++++++++ mysql-test/t/select.test | 14 ++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 206fa507615..99041701cb8 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2327,3 +2327,24 @@ select * from t2,t3 where t2.s = t3.s; s s two two drop table t1, t2, t3; +create table t1 (a integer, b integer, index(a), index(b)); +create table t2 (c integer, d integer, index(c), index(d)); +insert into t1 values (1,2), (2,2), (3,2), (4,2); +insert into t2 values (1,3), (2,3), (3,4), (4,4); +explain select * from t1 left join t2 on a=c where d in (4); +table type possible_keys key key_len ref rows Extra +t2 ref c,d d 5 const 2 Using where +t1 ALL a NULL NULL NULL 3 Using where +select * from t1 left join t2 on a=c where d in (4); +a b c d +3 2 3 4 +4 2 4 4 +explain select * from t1 left join t2 on a=c where d = 4; +table type possible_keys key key_len ref rows Extra +t2 ref c,d d 5 const 2 Using where +t1 ALL a NULL NULL NULL 3 Using where +select * from t1 left join t2 on a=c where d = 4; +a b c d +3 2 3 4 +4 2 4 4 +drop table t1, t2; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 7cb157f194e..11b3ae6aed1 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1874,3 +1874,17 @@ select * from t3 where s = 'one'; select * from t1,t2 where t1.s = t2.s; select * from t2,t3 where t2.s = t3.s; drop table t1, t2, t3; + +# +# Bug #3759 +# Both queries should produce identical plans and results. +# +create table t1 (a integer, b integer, index(a), index(b)); +create table t2 (c integer, d integer, index(c), index(d)); +insert into t1 values (1,2), (2,2), (3,2), (4,2); +insert into t2 values (1,3), (2,3), (3,4), (4,4); +explain select * from t1 left join t2 on a=c where d in (4); +select * from t1 left join t2 on a=c where d in (4); +explain select * from t1 left join t2 on a=c where d = 4; +select * from t1 left join t2 on a=c where d = 4; +drop table t1, t2; \ No newline at end of file From 0052dc8210b68a83736f547abf41f76a977e2826 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 24 Nov 2004 17:22:29 +0100 Subject: [PATCH 03/38] send_warning removed --- sql/protocol.cc | 30 ------------------------------ sql/sql_class.cc | 3 ++- sql/sql_parse.cc | 14 ++++++++------ 3 files changed, 10 insertions(+), 37 deletions(-) diff --git a/sql/protocol.cc b/sql/protocol.cc index 88be2710422..11a915ec151 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -131,36 +131,6 @@ void net_send_error(THD *thd, uint sql_errno, const char *err) DBUG_VOID_RETURN; } - -/* - Send a warning to the end user - - SYNOPSIS - send_warning() - thd Thread handler - sql_errno Warning number (error message) - err Error string. If not set, use ER(sql_errno) - - DESCRIPTION - Register the warning so that the user can get it with mysql_warnings() - Send an ok (+ warning count) to the end user. -*/ - -void send_warning(THD *thd, uint sql_errno, const char *err) -{ - DBUG_ENTER("send_warning"); - if (thd->spcont && - thd->spcont->find_handler(sql_errno, MYSQL_ERROR::WARN_LEVEL_WARN)) - { - DBUG_VOID_RETURN; - } - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, sql_errno, - err ? err : ER(sql_errno)); - send_ok(thd); - DBUG_VOID_RETURN; -} - - /* Write error package and flush to client It's a little too low level, but I don't want to use another buffer for diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ae2261e19f9..cc178a3121b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1754,7 +1754,8 @@ bool select_dumpvar::send_data(List &items) bool select_dumpvar::send_eof() { if (! row_count) - send_warning(thd, ER_SP_FETCH_NO_DATA); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_SP_FETCH_NO_DATA, ER(ER_SP_FETCH_NO_DATA)); ::send_ok(thd,row_count); return 0; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 89807765421..a966d596c7c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3579,9 +3579,10 @@ create_error: message in the error log, so we don't send it. */ if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread) - send_warning(thd,ER_WARNING_NOT_COMPLETE_ROLLBACK,0); - else - send_ok(thd); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARNING_NOT_COMPLETE_ROLLBACK, + ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)); + send_ok(thd); } else res= TRUE; @@ -3591,9 +3592,10 @@ create_error: if (!ha_rollback_to_savepoint(thd, lex->savepoint_name)) { if ((thd->options & OPTION_STATUS_NO_TRANS_UPDATE) && !thd->slave_thread) - send_warning(thd, ER_WARNING_NOT_COMPLETE_ROLLBACK, 0); - else - send_ok(thd); + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WARNING_NOT_COMPLETE_ROLLBACK, + ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)); + send_ok(thd); } else goto error; From 6f2cf12aa63a3b88ebf363576550ec5ae4954978 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Nov 2004 09:26:45 +0100 Subject: [PATCH 04/38] Fix for Bug#6148. Only rewind read position in binary log when the slave SQL thread is started. sql/slave.cc: Adding threads to init as parameter to init_master_info. Only rewind read position when starting SQL thread. sql/slave.h: Adding threads to init as parameter to init_master_info. Only rewind read position when starting SQL thread. sql/sql_repl.cc: Adding threads to init as parameter to init_master_info. Only rewind read position when starting SQL thread. sql/repl_failsafe.cc: Adding threads to init as parameter to init_master_info. Only rewind read position when starting SQL thread. --- mysql-test/r/rpl_start_stop_slave.result | 12 +++++++++ mysql-test/t/rpl_start_stop_slave.test | 34 ++++++++++++++++++++++++ sql/repl_failsafe.cc | 3 ++- sql/slave.cc | 14 +++++++--- sql/slave.h | 3 ++- sql/sql_repl.cc | 6 +++-- 6 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 mysql-test/r/rpl_start_stop_slave.result create mode 100644 mysql-test/t/rpl_start_stop_slave.test diff --git a/mysql-test/r/rpl_start_stop_slave.result b/mysql-test/r/rpl_start_stop_slave.result new file mode 100644 index 00000000000..1b4d87124d1 --- /dev/null +++ b/mysql-test/r/rpl_start_stop_slave.result @@ -0,0 +1,12 @@ +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(n int); +start slave; +stop slave io_thread; +start slave io_thread; +drop table t1; diff --git a/mysql-test/t/rpl_start_stop_slave.test b/mysql-test/t/rpl_start_stop_slave.test new file mode 100644 index 00000000000..903ff204194 --- /dev/null +++ b/mysql-test/t/rpl_start_stop_slave.test @@ -0,0 +1,34 @@ +source include/master-slave.inc; + +# +# Bug#6148 () +# +connection slave; +stop slave; + +# Let the master do lots of insertions +connection master; +create table t1(n int); +let $1=5000; +disable_query_log; +while ($1) +{ + eval insert into t1 values($1); + dec $1; +} +enable_query_log; +save_master_pos; + +connection slave; +start slave; +sleep 1; +stop slave io_thread; +start slave io_thread; +sync_with_master; + +connection master; +drop table t1; +save_master_pos; + +connection slave; +sync_with_master; diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 9fa6ea843f1..84640fbc968 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -892,7 +892,8 @@ int load_master_data(THD* thd) setting active_mi, because init_master_info() sets active_mi with defaults. */ - if (init_master_info(active_mi, master_info_file, relay_log_info_file, 0)) + if (init_master_info(active_mi, master_info_file, relay_log_info_file, + 0, (SLAVE_IO | SLAVE_SQL))) send_error(&thd->net, ER_MASTER_INFO); strmake(active_mi->master_log_name, row[0], sizeof(active_mi->master_log_name)); diff --git a/sql/slave.cc b/sql/slave.cc index 18e0ec5929f..7e544572755 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -137,7 +137,7 @@ int init_slave() } if (init_master_info(active_mi,master_info_file,relay_log_info_file, - !master_host)) + !master_host, (SLAVE_IO | SLAVE_SQL))) { sql_print_error("Failed to initialize the master info structure"); goto err; @@ -1616,7 +1616,8 @@ 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) + bool abort_if_no_master_info_file, + int thread_mask) { int fd,error; char fname[FN_REFLEN+128]; @@ -1630,8 +1631,15 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, last time. If this case pos_in_file would be set and we would get a crash when trying to read the signature for the binary relay log. + + We only rewind the read position if we are starting the SQL + thread. The handle_slave_sql thread assumes that the read + position is at the beginning of the file, and will read the + "signature" and then fast-forward to the last position read. */ - my_b_seek(mi->rli.cur_log, (my_off_t) 0); + if (thread_mask & SLAVE_SQL) { + my_b_seek(mi->rli.cur_log, (my_off_t) 0); + } DBUG_RETURN(0); } diff --git a/sql/slave.h b/sql/slave.h index eb54e258a96..a01ff93b4af 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -411,7 +411,8 @@ 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); + bool abort_if_no_master_info_file, + int thread_mask); void end_master_info(MASTER_INFO* mi); int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname); void end_relay_log_info(RELAY_LOG_INFO* rli); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 514fed226d2..9485031c144 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -662,7 +662,8 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) thread_mask &= thd->lex.slave_thd_opt; if (thread_mask) { - if (init_master_info(mi,master_info_file,relay_log_info_file, 0)) + if (init_master_info(mi,master_info_file,relay_log_info_file, 0, + thread_mask)) slave_errno=ER_MASTER_INFO; else if (server_id_supplied && *mi->host) slave_errno = start_slave_threads(0 /*no mutex */, @@ -867,7 +868,8 @@ int change_master(THD* thd, MASTER_INFO* mi) thd->proc_info = "Changing master"; LEX_MASTER_INFO* lex_mi = &thd->lex.mi; // TODO: see if needs re-write - if (init_master_info(mi, master_info_file, relay_log_info_file, 0)) + if (init_master_info(mi, master_info_file, relay_log_info_file, 0, + thread_mask)) { send_error(&thd->net, ER_MASTER_INFO); unlock_slave_threads(mi); From ea75abc51300e62ddff4842ddc11d378861aa07b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Nov 2004 16:13:06 +0100 Subject: [PATCH 05/38] Fixed BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY ...and for PURGE BEFORE too. (Don't fix_fields in the parser!) mysql-test/r/sp-error.result: New test case for BUG#6807 mysql-test/t/sp-error.test: New test case for BUG#6807 sql/sql_lex.h: Purge and kill query args not needed in lex. (Using value_list instead) sql/sql_parse.cc: Evaluate purge before and kill query args in mysql_execute_command instead of in the parser. (Makes it work with stored procedures) sql/sql_yacc.yy: Don't evaluate (fix_fields) args in the parser for purge before and kill query. (Doesn't work with stored procedures) --- mysql-test/r/sp-error.result | 13 +++++++++++++ mysql-test/t/sp-error.test | 22 ++++++++++++++++++++++ sql/sql_lex.h | 3 +-- sql/sql_parse.cc | 28 ++++++++++++++++++++++++++-- sql/sql_yacc.yy | 28 +++++++--------------------- 5 files changed, 69 insertions(+), 25 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 9bea0fe0d4c..642f1aedd78 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -460,4 +460,17 @@ end| call bug3294()| ERROR 42S02: Unknown table 't5' drop procedure bug3294| +drop procedure if exists bug6807| +create procedure bug6807() +begin +declare id int; +set id = connection_id(); +kill query id; +select 'Not reached'; +end| +call bug6807()| +ERROR 70100: Query execution was interrupted +call bug6807()| +ERROR 70100: Query execution was interrupted +drop procedure bug6807| drop table t1| diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index c04f8e6f9e9..c24f9df16be 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -632,6 +632,28 @@ end| call bug3294()| drop procedure bug3294| +# +# BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY +# +--disable_warnings +drop procedure if exists bug6807| +--enable_warnings +create procedure bug6807() +begin + declare id int; + + set id = connection_id(); + kill query id; + select 'Not reached'; +end| + +--error 1317 +call bug6807()| +--error 1317 +call bug6807()| + +drop procedure bug6807| + drop table t1| diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 605204fe35d..ce39a846fda 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -650,7 +650,6 @@ typedef struct st_lex char *help_arg; char *backup_dir; /* For RESTORE/BACKUP */ char* to_log; /* For PURGE MASTER LOGS TO */ - time_t purge_time; /* For PURGE MASTER LOGS BEFORE */ char* x509_subject,*x509_issuer,*ssl_cipher; char* found_colon; /* For multi queries - next query */ String *wild; @@ -694,7 +693,7 @@ typedef struct st_lex HA_CREATE_INFO create_info; LEX_MASTER_INFO mi; // used by CHANGE MASTER USER_RESOURCES mqh; - ulong thread_id,type; + ulong type; enum_sql_command sql_command, orig_sql_command; thr_lock_type lock_option, multi_lock_option; enum SSL_type ssl_type; /* defined in violite.h */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index fce8d294456..50d413ade38 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2327,10 +2327,24 @@ mysql_execute_command(THD *thd) } case SQLCOM_PURGE_BEFORE: { + Item *it; + if (check_global_access(thd, SUPER_ACL)) goto error; /* PURGE MASTER LOGS BEFORE 'data' */ - res = purge_master_logs_before_date(thd, lex->purge_time); + it= (Item *)lex->value_list.head(); + if (it->check_cols(1) || it->fix_fields(lex->thd, 0, &it)) + { + my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE"); + goto error; + } + it= new Item_func_unix_timestamp(it); + /* + it is OK only emulate fix_fieds, because we need only + value of constant + */ + it->quick_fix_field(); + res = purge_master_logs_before_date(thd, (ulong)it->val_int()); break; } #endif @@ -3505,8 +3519,18 @@ create_error: break; } case SQLCOM_KILL: - kill_one_thread(thd,lex->thread_id, lex->type & ONLY_KILL_QUERY); + { + Item *it= (Item *)lex->value_list.head(); + + if (it->fix_fields(lex->thd, 0, &it) || it->check_cols(1)) + { + my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), + MYF(0)); + goto error; + } + kill_one_thread(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY); break; + } #ifndef NO_EMBEDDED_ACCESS_CHECKS case SQLCOM_SHOW_GRANTS: if ((thd->priv_user && diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index dd9cd4af0f3..2316145ac65 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6280,19 +6280,10 @@ purge_option: } | BEFORE_SYM expr { - if ($2->check_cols(1) || $2->fix_fields(Lex->thd, 0, &$2)) - { - my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE"); - YYABORT; - } - Item *tmp= new Item_func_unix_timestamp($2); - /* - it is OK only emulate fix_fieds, because we need only - value of constant - */ - tmp->quick_fix_field(); - Lex->sql_command = SQLCOM_PURGE_BEFORE; - Lex->purge_time= (ulong) tmp->val_int(); + LEX *lex= Lex; + lex->value_list.empty(); + lex->value_list.push_front($2); + lex->sql_command= SQLCOM_PURGE_BEFORE; } ; @@ -6302,14 +6293,9 @@ kill: KILL_SYM kill_option expr { LEX *lex=Lex; - if ($3->fix_fields(lex->thd, 0, &$3) || $3->check_cols(1)) - { - my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), - MYF(0)); - YYABORT; - } - lex->sql_command=SQLCOM_KILL; - lex->thread_id= (ulong) $3->val_int(); + lex->value_list.empty(); + lex->value_list.push_front($3); + lex->sql_command= SQLCOM_KILL; }; kill_option: From 8de438d5db09ef1409c79444d6d44a9a2679c080 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Nov 2004 17:02:44 +0100 Subject: [PATCH 06/38] order by group_func --- mysql-test/r/order_by.result | 7 +++++++ mysql-test/t/order_by.test | 6 ++++++ sql/sql_select.cc | 14 ++++++++------ 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 15643f29513..abc48783cf4 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -733,3 +733,10 @@ xxxxxxxxxxxxxxxxxxxaa xxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxz drop table t1; +create table t1 (a int not null, b int not null, c int not null); +insert t1 values (1,1,1),(1,1,2),(1,2,1); +select a, b from t1 group by a, b order by sum(c); +a b +1 2 +1 1 +drop table t1; diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 988c106bf21..dd36cd95969 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -500,3 +500,9 @@ insert into t1 set a = concat(repeat('x', 19), 'aa'); set max_sort_length=20; select a from t1 order by a; drop table t1; + +create table t1 (a int not null, b int not null, c int not null); +insert t1 values (1,1,1),(1,1,2),(1,2,1); +select a, b from t1 group by a, b order by sum(c); +drop table t1; + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4c652ee972a..792083350af 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -262,11 +262,13 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array, save_allow_sum_func= thd->allow_sum_func; thd->allow_sum_func= 0; - res= (setup_conds(thd, tables, conds) || - setup_order(thd, ref_pointer_array, tables, fields, all_fields, - order) || - setup_group(thd, ref_pointer_array, tables, fields, all_fields, - group, hidden_group_fields)); + res= setup_conds(thd, tables, conds); + thd->allow_sum_func= save_allow_sum_func; + res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, + order); + thd->allow_sum_func= 0; + res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields, + group, hidden_group_fields); thd->allow_sum_func= save_allow_sum_func; DBUG_RETURN(res); } @@ -11330,7 +11332,7 @@ int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables, setup_group() thd Thread handler ref_pointer_array We store references to all fields that was not in - 'fields' here. + 'fields' here. fields All fields in the select part. Any item in 'order' that is part of these list is replaced by a pointer to this fields. From 75e2c2fd998f310ceeebccc81f1de9e5daf3155d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Nov 2004 21:55:49 +0100 Subject: [PATCH 07/38] WL#2050 - CREATE USER and DROP USER and RENAME USER Added new commands CREATE USER and RENAME USER. Changed behaviour of DROP USER. Changed an error messages for the new commands. Docs/mysqld_error.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. include/mysqld_error.h: WL#2050 - CREATE USER and DROP USER and RENAME USER Changed an error code for more general use. mysql-test/r/grant.result: WL#2050 - CREATE USER and DROP USER and RENAME USER Changed test results. mysql-test/r/grant2.result: WL#2050 - CREATE USER and DROP USER and RENAME USER New test results. mysql-test/r/ps_1general.result: WL#2050 - CREATE USER and DROP USER and RENAME USER Changed test results. mysql-test/t/grant.test: WL#2050 - CREATE USER and DROP USER and RENAME USER Updated old tests for new behaviour of DROP USER. It does now implicitly remove all privileges and does not fail when privileges are still in place. Fixed a typo, which left an user in the database, whereby other tests could be confused. Added a DROP USER for another test user. mysql-test/t/grant2.test: WL#2050 - CREATE USER and DROP USER and RENAME USER Added new tests for the new features. sql/share/czech/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/danish/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/dutch/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/english/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/estonian/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/french/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/german/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/greek/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/hungarian/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/italian/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/japanese/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/korean/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/norwegian-ny/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/norwegian/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/polish/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/portuguese/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/romanian/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/russian/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/serbian/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/slovak/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/spanish/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/swedish/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/share/ukrainian/errmsg.txt: WL#2050 - CREATE USER and DROP USER and RENAME USER Modified an error message for more general use. sql/sql_acl.cc: WL#2050 - CREATE USER and DROP USER and RENAME USER Added a destructor for the GRANT_TABLE object to get rid of a hash_column in cases where a nonsense row was read from the privilege tables. Added code to delete such an object when it is not entered into the column_priv_hash due to a nonsense row. Added function comments to two unmodified functions. Replaced mysql_drop_user() by the implementation of all of the functions as specified in the Low Level Design. sql/sql_acl.h: WL#2050 - CREATE USER and DROP USER and RENAME USER Added prototypes for new functions. sql/sql_lex.h: WL#2050 - CREATE USER and DROP USER and RENAME USER Added new command codes for CREATE USER and RENAME USER. sql/sql_parse.cc: WL#2050 - CREATE USER and DROP USER and RENAME USER Added case clauses for the new commands CREATE USER and RENAME USER. sql/sql_yacc.yy: WL#2050 - CREATE USER and DROP USER and RENAME USER Added syntax for the new commands CREATE USER and RENAME USER, reworked DROP USER, introduced a new 'user_list' and 'rename_list', renamed the old 'user_list' to 'grant_list'. The difference is that 'grant_list' contains 'grant_user' (with optional IDENTIFIED BY), while 'user_list' contains 'user'. Concentrated privilege initializazions into a new section 'clear_privileges'. --- Docs/mysqld_error.txt | 4 +- include/mysqld_error.h | 2 +- mysql-test/r/grant.result | 7 +- mysql-test/r/grant2.result | 163 ++++++ mysql-test/r/ps_1general.result | 6 +- mysql-test/t/grant.test | 9 +- mysql-test/t/grant2.test | 147 +++++ sql/share/czech/errmsg.txt | 2 +- sql/share/danish/errmsg.txt | 2 +- sql/share/dutch/errmsg.txt | 2 +- sql/share/english/errmsg.txt | 2 +- sql/share/estonian/errmsg.txt | 2 +- sql/share/french/errmsg.txt | 2 +- sql/share/german/errmsg.txt | 2 +- sql/share/greek/errmsg.txt | 2 +- sql/share/hungarian/errmsg.txt | 2 +- sql/share/italian/errmsg.txt | 2 +- sql/share/japanese/errmsg.txt | 2 +- sql/share/korean/errmsg.txt | 2 +- sql/share/norwegian-ny/errmsg.txt | 2 +- sql/share/norwegian/errmsg.txt | 2 +- sql/share/polish/errmsg.txt | 2 +- sql/share/portuguese/errmsg.txt | 2 +- sql/share/romanian/errmsg.txt | 2 +- sql/share/russian/errmsg.txt | 2 +- sql/share/serbian/errmsg.txt | 2 +- sql/share/slovak/errmsg.txt | 2 +- sql/share/spanish/errmsg.txt | 2 +- sql/share/swedish/errmsg.txt | 2 +- sql/share/ukrainian/errmsg.txt | 2 +- sql/sql_acl.cc | 879 +++++++++++++++++++++++++----- sql/sql_acl.h | 2 + sql/sql_lex.h | 3 +- sql/sql_parse.cc | 34 +- sql/sql_yacc.yy | 103 ++-- 35 files changed, 1179 insertions(+), 226 deletions(-) diff --git a/Docs/mysqld_error.txt b/Docs/mysqld_error.txt index c164e8bd3a0..6370d8aac46 100644 --- a/Docs/mysqld_error.txt +++ b/Docs/mysqld_error.txt @@ -539,8 +539,8 @@ character-set=latin1 "Using storage engine %s for table '%s'", #define ER_CANT_AGGREGATE_2COLLATIONS 1267 "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -#define ER_DROP_USER 1268 -"Can't drop one or more of the requested users", +#define ER_HANDLE_USER 1268 +"Operation %s failed for %d of the requested users", #define ER_REVOKE_GRANTS 1269 "Can't revoke all privileges, grant for one or more of the requested users", #define ER_CANT_AGGREGATE_3COLLATIONS 1270 diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 478b46dd246..f5994e8e71d 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -284,7 +284,7 @@ #define ER_WARN_DATA_TRUNCATED 1265 #define ER_WARN_USING_OTHER_HANDLER 1266 #define ER_CANT_AGGREGATE_2COLLATIONS 1267 -#define ER_DROP_USER 1268 +#define ER_HANDLE_USER 1268 #define ER_REVOKE_GRANTS 1269 #define ER_CANT_AGGREGATE_3COLLATIONS 1270 #define ER_CANT_AGGREGATE_NCOLLATIONS 1271 diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 1ac6165e383..262afc3ce2f 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -218,17 +218,19 @@ 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 option from drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; +ERROR HY000: Can't revoke all privileges, grant for one or more of the requested users drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; +ERROR HY000: Operation DROP USER failed for 4 of the requested users drop table t1; grant usage on *.* to mysqltest_1@localhost identified by "password"; -grant select, update, insert on test.* to mysqltest@localhost; +grant select, update, insert on test.* to mysqltest_1@localhost; show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' +GRANT SELECT, INSERT, UPDATE ON `test`.* TO 'mysqltest_1'@'localhost' drop user mysqltest_1@localhost; SET NAMES koi8r; CREATE DATABASE ÂÄ; @@ -252,6 +254,7 @@ Grants for GRANT USAGE ON *.* TO 'ÀÚÅÒ'@'localhost' GRANT SELECT (ËÏÌ) ON `ÂÄ`.`ÔÁÂ` TO 'ÀÚÅÒ'@'localhost' REVOKE SELECT (ËÏÌ) ON ÂÄ.ÔÁ FROM ÀÚÅÒ@localhost; +DROP USER ÀÚÅÒ@localhost; DROP DATABASE ÂÄ; SET NAMES latin1; USE test; diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 9e1e5d50f31..fee9150ca50 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -60,3 +60,166 @@ use test; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; +set sql_mode='maxdb'; +drop table if exists t1, t2; +create table t1(c1 int); +create table t2(c1 int, c2 int); +create user 'mysqltest_1'; +create user 'mysqltest_1'; +ERROR HY000: Operation CREATE USER failed for 1 of the requested users +create user 'mysqltest_2' identified by 'Mysqltest-2'; +create user 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; +grant select on *.* to 'mysqltest_2'; +grant insert on test.* to 'mysqltest_2'; +grant update on test.t1 to 'mysqltest_2'; +grant update (c2) on test.t2 to 'mysqltest_2'; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; +host user password +% mysqltest_1 +% mysqltest_2 *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 +% mysqltest_3 fffffffffffffffffffffffffffffffffffffffff +select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user; +host db user +% test mysqltest_2 +select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name; +host db user table_name +% test mysqltest_2 t1 +% test mysqltest_2 t2 +select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name; +host db user table_name column_name +% test mysqltest_2 t2 c2 +show grants for 'mysqltest_1'; +Grants for mysqltest_1@% +GRANT USAGE ON *.* TO 'mysqltest_1'@'%' +show grants for 'mysqltest_2'; +Grants for mysqltest_2@% +GRANT SELECT ON *.* TO 'mysqltest_2'@'%' IDENTIFIED BY PASSWORD '*BD447CBA355AF58578D3AE33BA2E2CD388BA08D1' +GRANT INSERT ON "test".* TO 'mysqltest_2'@'%' +GRANT UPDATE (c2) ON "test"."t2" TO 'mysqltest_2'@'%' +GRANT UPDATE ON "test"."t1" TO 'mysqltest_2'@'%' +drop user 'mysqltest_1'; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; +host user password +% mysqltest_2 *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 +% mysqltest_3 fffffffffffffffffffffffffffffffffffffffff +select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user; +host db user +% test mysqltest_2 +select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name; +host db user table_name +% test mysqltest_2 t1 +% test mysqltest_2 t2 +select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name; +host db user table_name column_name +% test mysqltest_2 t2 c2 +show grants for 'mysqltest_1'; +ERROR 42000: There is no such grant defined for user 'mysqltest_1' on host '%' +rename user 'mysqltest_2' to 'mysqltest_1'; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; +host user password +% mysqltest_1 *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 +% mysqltest_3 fffffffffffffffffffffffffffffffffffffffff +select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user; +host db user +% test mysqltest_1 +select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name; +host db user table_name +% test mysqltest_1 t1 +% test mysqltest_1 t2 +select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name; +host db user table_name column_name +% test mysqltest_1 t2 c2 +show grants for 'mysqltest_1'; +Grants for mysqltest_1@% +GRANT SELECT ON *.* TO 'mysqltest_1'@'%' IDENTIFIED BY PASSWORD '*BD447CBA355AF58578D3AE33BA2E2CD388BA08D1' +GRANT INSERT ON "test".* TO 'mysqltest_1'@'%' +GRANT UPDATE (c2) ON "test"."t2" TO 'mysqltest_1'@'%' +GRANT UPDATE ON "test"."t1" TO 'mysqltest_1'@'%' +drop user 'mysqltest_1', 'mysqltest_3'; +drop table t1, t2; +insert into mysql.db set user='mysqltest_1', db='%', host='%'; +flush privileges; +show grants for 'mysqltest_1'; +ERROR 42000: There is no such grant defined for user 'mysqltest_1' on host '%' +revoke all privileges, grant option from 'mysqltest_1'; +ERROR HY000: Can't revoke all privileges, grant for one or more of the requested users +drop user 'mysqltest_1'; +select host,db,user from mysql.db where user = 'mysqltest_1' order by host,db,user; +host db user +insert into mysql.tables_priv set host='%', db='test', user='mysqltest_1', table_name='t1'; +flush privileges; +show grants for 'mysqltest_1'; +ERROR 42000: There is no such grant defined for user 'mysqltest_1' on host '%' +drop user 'mysqltest_1'; +select host,db,user,table_name from mysql.tables_priv where user = 'mysqltest_1' order by host,db,user,table_name; +host db user table_name +insert into mysql.columns_priv set host='%', db='test', user='mysqltest_1', table_name='t1', column_name='c1'; +flush privileges; +show grants for 'mysqltest_1'; +ERROR 42000: There is no such grant defined for user 'mysqltest_1' on host '%' +drop user 'mysqltest_1'; +select host,db,user,table_name,column_name from mysql.columns_priv where user = 'mysqltest_1' order by host,db,user,table_name,column_name; +host db user table_name column_name +create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +create user 'mysqltest_1', 'mysqltest_2' identified by 'Mysqltest-2', 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; +rename user 'mysqltest_1' to 'mysqltest_1a', 'mysqltest_2' TO 'mysqltest_2a', 'mysqltest_3' TO 'mysqltest_3a'; +drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +ERROR HY000: Operation DROP USER failed for 3 of the requested users +drop user 'mysqltest_1a', 'mysqltest_2a', 'mysqltest_3a'; +create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +create user 'mysqltest_1a', 'mysqltest_2', 'mysqltest_3a'; +ERROR HY000: Operation CREATE USER failed for 1 of the requested users +rename user 'mysqltest_1a' to 'mysqltest_1b', 'mysqltest_2a' TO 'mysqltest_2b', 'mysqltest_3a' TO 'mysqltest_3b'; +ERROR HY000: Operation RENAME USER failed for 1 of the requested users +drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +drop user 'mysqltest_1b', 'mysqltest_2b', 'mysqltest_3b'; +ERROR HY000: Operation DROP USER failed for 1 of the requested users +create user 'mysqltest_2' identified by 'Mysqltest-2'; +drop user 'mysqltest_2' identified by 'Mysqltest-2'; +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 'identified by 'Mysqltest-2'' at line 1 +create user '%@b'@'b'; +show grants for '%@b'@'b'; +Grants for %@b@b +GRANT USAGE ON *.* TO '%@b'@'b' +grant select on mysql.* to '%@b'@'b'; +show grants for '%@b'@'b'; +Grants for %@b@b +GRANT USAGE ON *.* TO '%@b'@'b' +GRANT SELECT ON "mysql".* TO '%@b'@'b' +rename user '%@b'@'b' to '%@a'@'a'; +show grants for '%@b'@'b'; +ERROR 42000: There is no such grant defined for user '%@b' on host 'b' +show grants for '%@a'@'a'; +Grants for %@a@a +GRANT USAGE ON *.* TO '%@a'@'a' +GRANT SELECT ON "mysql".* TO '%@a'@'a' +drop user '%@a'@'a'; +create user mysqltest_2@localhost; +grant usage on *.* to mysqltest_2@localhost with grant option; +select host,user,password from mysql.user order by host,user,password; +ERROR 42000: Access denied for user 'mysqltest_2'@'localhost' to database 'mysql' +create user mysqltest_A@'%'; +rename user mysqltest_A@'%' to mysqltest_B@'%'; +drop user mysqltest_B@'%'; +drop user mysqltest_2@localhost; +create user mysqltest_3@localhost; +grant all privileges on mysql.* to mysqltest_3@localhost; +select host,user,password from mysql.user order by host,user,password; +host user password +% mysqltest_2 *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 +127.0.0.1 root +chilla% +chilla% root +localhost +localhost mysqltest_3 +localhost root +insert into mysql.user set host='%', user='mysqltest_B'; +create user mysqltest_A@'%'; +ERROR 42000: Access denied for user 'mysqltest_3'@'localhost' to database 'mysql' +rename user mysqltest_B@'%' to mysqltest_C@'%'; +ERROR 42000: Access denied for user 'mysqltest_3'@'localhost' to database 'mysql' +drop user mysqltest_B@'%'; +ERROR 42000: Access denied for user 'mysqltest_3'@'localhost' to database 'mysql' +drop user mysqltest_B@'%'; +drop user mysqltest_3@localhost; diff --git a/mysql-test/r/ps_1general.result b/mysql-test/r/ps_1general.result index e8d8e4063f1..9b12b0baa1d 100644 --- a/mysql-test/r/ps_1general.result +++ b/mysql-test/r/ps_1general.result @@ -835,19 +835,19 @@ identified by 'looser' ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' drop table mysqltest.t9 ; show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' show grants for second_user@localhost ; Grants for second_user@localhost GRANT USAGE ON *.* TO 'second_user'@'localhost' IDENTIFIED BY PASSWORD '*13843FE600B19A81E32AF50D4A6FED25875FF1F3' -GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' GRANT SELECT ON `mysqltest`.`t1` TO 'second_user'@'localhost' +GRANT SELECT ON `mysqltest`.`t9` TO 'second_user'@'localhost' prepare s_t1 from 'select a as my_col from t1' ; execute s_t1 ; my_col diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index dfd5f4db7c6..c004699d901 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -162,16 +162,18 @@ 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 1268 +# Drop user now implicitly revokes all privileges. drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; +--error 1269 revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; +--error 1268 drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; drop table t1; grant usage on *.* to mysqltest_1@localhost identified by "password"; -grant select, update, insert on test.* to mysqltest@localhost; +grant select, update, insert on test.* to mysqltest_1@localhost; show grants for mysqltest_1@localhost; drop user mysqltest_1@localhost; @@ -195,6 +197,9 @@ GRANT SELECT ( SHOW GRANTS FOR ÀÚÅÒ@localhost; REVOKE SELECT (ËÏÌ) ON ÂÄ.ÔÁ FROM ÀÚÅÒ@localhost; +# Revoke does not drop user. Leave a clean user table for the next tests. +DROP USER ÀÚÅÒ@localhost; + DROP DATABASE ÂÄ; SET NAMES latin1; diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index fe4a5b55b82..c439bd05d2f 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -78,3 +78,150 @@ use test; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; flush privileges; + +# +# Create and drop user +# +set sql_mode='maxdb'; +--disable_warnings +drop table if exists t1, t2; +--enable_warnings +create table t1(c1 int); +create table t2(c1 int, c2 int); +# +# Three forms of CREATE USER +create user 'mysqltest_1'; +--error 1268 +create user 'mysqltest_1'; +create user 'mysqltest_2' identified by 'Mysqltest-2'; +create user 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; +grant select on *.* to 'mysqltest_2'; +grant insert on test.* to 'mysqltest_2'; +grant update on test.t1 to 'mysqltest_2'; +grant update (c2) on test.t2 to 'mysqltest_2'; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; +select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user; +select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name; +select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name; +show grants for 'mysqltest_1'; +show grants for 'mysqltest_2'; +# +# Drop +drop user 'mysqltest_1'; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; +select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user; +select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name; +select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name; +--error 1141 +show grants for 'mysqltest_1'; +# +# Rename +rename user 'mysqltest_2' to 'mysqltest_1'; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; +select host,db,user from mysql.db where user like 'mysqltest_%' order by host,db,user; +select host,db,user,table_name from mysql.tables_priv where user like 'mysqltest_%' order by host,db,user,table_name; +select host,db,user,table_name,column_name from mysql.columns_priv where user like 'mysqltest_%' order by host,db,user,table_name,column_name; +show grants for 'mysqltest_1'; +drop user 'mysqltest_1', 'mysqltest_3'; +# +# Grant must not create user +#grant all on test.t1 to 'mysqltest_1'; +#drop user 'mysqltest_1'; +# +# Cleanup +drop table t1, t2; +# +# Add a stray record +insert into mysql.db set user='mysqltest_1', db='%', host='%'; +flush privileges; +--error 1141 +show grants for 'mysqltest_1'; +--error 1269 +revoke all privileges, grant option from 'mysqltest_1'; +drop user 'mysqltest_1'; +select host,db,user from mysql.db where user = 'mysqltest_1' order by host,db,user; +# +# Add a stray record +insert into mysql.tables_priv set host='%', db='test', user='mysqltest_1', table_name='t1'; +flush privileges; +--error 1141 +show grants for 'mysqltest_1'; +drop user 'mysqltest_1'; +select host,db,user,table_name from mysql.tables_priv where user = 'mysqltest_1' order by host,db,user,table_name; +# +# Add a stray record +insert into mysql.columns_priv set host='%', db='test', user='mysqltest_1', table_name='t1', column_name='c1'; +flush privileges; +--error 1141 +show grants for 'mysqltest_1'; +drop user 'mysqltest_1'; +select host,db,user,table_name,column_name from mysql.columns_priv where user = 'mysqltest_1' order by host,db,user,table_name,column_name; +# +# Handle multi user lists +create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +create user 'mysqltest_1', 'mysqltest_2' identified by 'Mysqltest-2', 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; +rename user 'mysqltest_1' to 'mysqltest_1a', 'mysqltest_2' TO 'mysqltest_2a', 'mysqltest_3' TO 'mysqltest_3a'; +--error 1268 +drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +drop user 'mysqltest_1a', 'mysqltest_2a', 'mysqltest_3a'; +# +# Let one of multiple users fail +create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +--error 1268 +create user 'mysqltest_1a', 'mysqltest_2', 'mysqltest_3a'; +--error 1268 +rename user 'mysqltest_1a' to 'mysqltest_1b', 'mysqltest_2a' TO 'mysqltest_2b', 'mysqltest_3a' TO 'mysqltest_3b'; +drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; +--error 1268 +drop user 'mysqltest_1b', 'mysqltest_2b', 'mysqltest_3b'; +# +# Obsolete syntax has been dropped +create user 'mysqltest_2' identified by 'Mysqltest-2'; +--error 1064 +drop user 'mysqltest_2' identified by 'Mysqltest-2'; +# +# Strange user names +create user '%@b'@'b'; +show grants for '%@b'@'b'; +grant select on mysql.* to '%@b'@'b'; +show grants for '%@b'@'b'; +rename user '%@b'@'b' to '%@a'@'a'; +--error 1141 +show grants for '%@b'@'b'; +show grants for '%@a'@'a'; +drop user '%@a'@'a'; +# +# USAGE WITH GRANT OPTION is sufficient. +create user mysqltest_2@localhost; +grant usage on *.* to mysqltest_2@localhost with grant option; +connect (user2,localhost,mysqltest_2,,); +connection user2; +--error 1044 +select host,user,password from mysql.user order by host,user,password; +create user mysqltest_A@'%'; +rename user mysqltest_A@'%' to mysqltest_B@'%'; +drop user mysqltest_B@'%'; +disconnect user2; +connection default; +drop user mysqltest_2@localhost; +# +# ALL PRIVILEGES without GRANT OPTION is not sufficient. +create user mysqltest_3@localhost; +grant all privileges on mysql.* to mysqltest_3@localhost; +connect (user3,localhost,mysqltest_3,,); +connection user3; +select host,user,password from mysql.user order by host,user,password; +insert into mysql.user set host='%', user='mysqltest_B'; +--error 1044 +create user mysqltest_A@'%'; +--error 1044 +rename user mysqltest_B@'%' to mysqltest_C@'%'; +--error 1044 +drop user mysqltest_B@'%'; +disconnect user3; +connection default; +drop user mysqltest_B@'%'; +drop user mysqltest_3@localhost; +# + diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 55a8499145a..54d22e62dba 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -296,7 +296,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index ee1341cf095..7385be9545c 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -287,7 +287,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 26ff759ca40..7015ed90789 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -296,7 +296,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 8abb684fe11..54ca033657e 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -284,7 +284,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 1211bd305dd..b89ebb42500 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -289,7 +289,7 @@ character-set=latin7 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 5c54b5e01a8..4e370a63099 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -284,7 +284,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 4d1a4a17ebe..b4afa45ee46 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -297,7 +297,7 @@ character-set=latin1 "Daten abgeschnitten für Spalte '%s' in Zeile %ld", "Für Tabelle '%s' wird Speicher-Engine %s benutzt", "Unerlaubte Vermischung der Kollationen (%s,%s) und (%s,%s) für die Operation '%s'", -"Kann einen oder mehrere der angegebenen Benutzer nicht löschen", +"Das Kommando %s scheiterte für %d von den betroffenen Benutzern", "Kann nicht alle Berechtigungen widerrufen, grant for one or more of the requested users", "Unerlaubte Vermischung der Kollationen (%s,%s), (%s,%s), (%s,%s) für die Operation '%s'", "Unerlaubte Vermischung der Kollationen für die Operation '%s'", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 146d25cfaee..afc91d0c69e 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -284,7 +284,7 @@ character-set=greek "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index be195b86503..61c112170b2 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -289,7 +289,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 685d2d0c972..e6a00332093 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -284,7 +284,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 665e1991198..98282af52d6 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -288,7 +288,7 @@ character-set=ujis "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index d4f59b768ff..b10a83beee9 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -284,7 +284,7 @@ character-set=euckr "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 780bfd8d8ca..e5a41b7d3d9 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -286,7 +286,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index d723d0cc475..334313c1916 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -286,7 +286,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index b3242c46310..0d8deb30e77 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -289,7 +289,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index b2a993bf002..e47a69a5c25 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -286,7 +286,7 @@ character-set=latin1 "Dado truncado para coluna '%s' na linha %ld", "Usando engine de armazenamento %s para tabela '%s'", "Combinação ilegal de collations (%s,%s) e (%s,%s) para operação '%s'", -"Não pode remover um ou mais dos usuários pedidos", +"Operation %s failed for %d of the requested users", "Não pode revocar todos os privilégios, grant para um ou mais dos usuários pedidos", "Ilegal combinação de collations (%s,%s), (%s,%s), (%s,%s) para operação '%s'", "Ilegal combinação de collations para operação '%s'", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 7f5ef856d3a..c5a63223c22 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -289,7 +289,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 74cafac8b52..04c51d5f532 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -289,7 +289,7 @@ character-set=koi8r "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 9a09358a35a..f267faeccbd 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -277,7 +277,7 @@ character-set=cp1250 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 4c694fecc88..8b7bb730cf0 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -292,7 +292,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 94316edd083..c0e663d6484 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -288,7 +288,7 @@ character-set=latin1 "Datos truncados para columna '%s' en la línea %ld", "Usando motor de almacenamiento %s para tabla '%s'", "Ilegal mezcla de collations (%s,%s) y (%s,%s) para operación '%s'", -"No puede remover uno o mas de los usuarios solicitados", +"Operation %s failed for %d of the requested users", "No puede revocar todos los privilegios, derecho para uno o mas de los usuarios solicitados", "Ilegal mezcla de collations (%s,%s), (%s,%s), (%s,%s) para operación '%s'", "Ilegal mezcla de collations para operación '%s'", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index cd57653969f..831ccfbe978 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -284,7 +284,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Använder handler %s för tabell '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 0b3400a4e88..46a0adf922f 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -290,7 +290,7 @@ character-set=koi8u "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Can't drop one or more of the requested users", +"Operation %s failed for %d of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 9ce00a01e31..d3bfb5b4d1d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -919,7 +919,7 @@ static void acl_update_user(const char *user, const char *host, { if (!acl_user->host.hostname && !host[0] || acl_user->host.hostname && - !my_strcasecmp(&my_charset_latin1, host, acl_user->host.hostname)) + !my_strcasecmp(system_charset_info, host, acl_user->host.hostname)) { acl_user->access=privileges; if (mqh->bits & 1) @@ -998,7 +998,7 @@ static void acl_update_db(const char *user, const char *host, const char *db, { if (!acl_db->host.hostname && !host[0] || acl_db->host.hostname && - !my_strcasecmp(&my_charset_latin1, host, acl_db->host.hostname)) + !my_strcasecmp(system_charset_info, host, acl_db->host.hostname)) { if (!acl_db->db && !db[0] || acl_db->db && !strcmp(db,acl_db->db)) @@ -1141,7 +1141,7 @@ static void init_check_host(void) DBUG_ENTER("init_check_host"); VOID(my_init_dynamic_array(&acl_wild_hosts,sizeof(struct acl_host_and_ip), acl_users.elements,1)); - VOID(hash_init(&acl_check_hosts,&my_charset_latin1,acl_users.elements,0,0, + VOID(hash_init(&acl_check_hosts,system_charset_info,acl_users.elements,0,0, (hash_get_key) check_get_key,0,0)); if (!allow_all_hosts) { @@ -1157,7 +1157,7 @@ static void init_check_host(void) { // Check if host already exists acl_host_and_ip *acl=dynamic_element(&acl_wild_hosts,j, acl_host_and_ip *); - if (!my_strcasecmp(&my_charset_latin1, + if (!my_strcasecmp(system_charset_info, acl_user->host.hostname, acl->hostname)) break; // already stored } @@ -1233,7 +1233,7 @@ bool check_change_password(THD *thd, const char *host, const char *user, } if (!thd->slave_thread && (strcmp(thd->user,user) || - my_strcasecmp(&my_charset_latin1, host, thd->host_or_ip))) + my_strcasecmp(system_charset_info, host, thd->host_or_ip))) { if (check_access(thd, UPDATE_ACL, "mysql",0,1,0)) return(1); @@ -1402,7 +1402,7 @@ static bool compare_hostname(const acl_host_and_ip *host, const char *hostname, return (tmp & host->ip_mask) == host->ip; } return (!host->hostname || - (hostname && !wild_case_compare(&my_charset_latin1, + (hostname && !wild_case_compare(system_charset_info, hostname,host->hostname)) || (ip && !wild_compare(ip,host->hostname,0))); } @@ -1415,7 +1415,7 @@ bool hostname_requires_resolving(const char *hostname) int namelen= strlen(hostname); int lhlen= strlen(my_localhost); if ((namelen == lhlen) && - !my_strnncoll(&my_charset_latin1, (const uchar *)hostname, namelen, + !my_strnncoll(system_charset_info, (const uchar *)hostname, namelen, (const uchar *)my_localhost, strlen(my_localhost))) return FALSE; for (; (cur=*hostname); hostname++) @@ -1464,8 +1464,8 @@ static bool update_user_table(THD *thd, const char *host, const char *user, if (!(table=open_ltable(thd,&tables,TL_WRITE))) DBUG_RETURN(1); /* purecov: deadcode */ - table->field[0]->store(host,(uint) strlen(host), &my_charset_latin1); - table->field[1]->store(user,(uint) strlen(user), &my_charset_latin1); + table->field[0]->store(host,(uint) strlen(host), system_charset_info); + table->field[1]->store(user,(uint) strlen(user), system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, @@ -1478,7 +1478,7 @@ static bool update_user_table(THD *thd, const char *host, const char *user, DBUG_RETURN(1); /* purecov: deadcode */ } store_record(table,record[1]); - table->field[2]->store(new_password, new_password_len, &my_charset_latin1); + table->field[2]->store(new_password, new_password_len, system_charset_info); if ((error=table->file->update_row(table->record[1],table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ @@ -1546,8 +1546,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, password=combo.password.str; } - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(combo.user.str,combo.user.length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0], 0, (byte*) table->field[0]->ptr, @@ -1581,11 +1581,11 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, old_row_exists = 0; restore_record(table,default_values); // cp empty row from default_values table->field[0]->store(combo.host.str,combo.host.length, - &my_charset_latin1); + system_charset_info); table->field[1]->store(combo.user.str,combo.user.length, - &my_charset_latin1); + system_charset_info); table->field[2]->store(password, password_len, - &my_charset_latin1); + system_charset_info); } else { @@ -1596,14 +1596,14 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, DBUG_ASSERT(combo.host.str); if (thd->user && combo.password.str && (strcmp(thd->user,combo.user.str) || - my_strcasecmp(&my_charset_latin1, + my_strcasecmp(system_charset_info, combo.host.str, thd->host_or_ip)) && check_access(thd, UPDATE_ACL, "mysql",0,1,0)) goto end; old_row_exists = 1; store_record(table,record[1]); // Save copy for update if (combo.password.str) // If password given - table->field[2]->store(password, password_len, &my_charset_latin1); + table->field[2]->store(password, password_len, system_charset_info); else if (!rights && !revoke_grant && lex->ssl_type == SSL_TYPE_NOT_SPECIFIED && !lex->mqh.bits) { @@ -1648,13 +1648,13 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, table->field[27]->store("", 0, &my_charset_latin1); if (lex->ssl_cipher) table->field[25]->store(lex->ssl_cipher, - strlen(lex->ssl_cipher), &my_charset_latin1); + strlen(lex->ssl_cipher), system_charset_info); if (lex->x509_issuer) table->field[26]->store(lex->x509_issuer, - strlen(lex->x509_issuer), &my_charset_latin1); + strlen(lex->x509_issuer), system_charset_info); if (lex->x509_subject) table->field[27]->store(lex->x509_subject, - strlen(lex->x509_subject), &my_charset_latin1); + strlen(lex->x509_subject), system_charset_info); break; case SSL_TYPE_NOT_SPECIFIED: break; @@ -1756,9 +1756,9 @@ static int replace_db_table(TABLE *table, const char *db, DBUG_RETURN(-1); } - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, (byte*) table->field[0]->ptr, @@ -1772,9 +1772,9 @@ static int replace_db_table(TABLE *table, const char *db, } old_row_exists = 0; restore_record(table,default_values); // cp empty row from default_values - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); } else { @@ -1862,6 +1862,7 @@ public: GRANT_TABLE(const char *h, const char *d,const char *u, const char *t, ulong p, ulong c); GRANT_TABLE (TABLE *form, TABLE *col_privs); + ~GRANT_TABLE(); bool ok() { return privs != 0 || cols != 0; } }; @@ -1887,7 +1888,7 @@ GRANT_TABLE::GRANT_TABLE(const char *h, const char *d,const char *u, key_length =(uint) strlen(d)+(uint) strlen(u)+(uint) strlen(t)+3; hash_key = (char*) alloc_root(&memex,key_length); strmov(strmov(strmov(hash_key,user)+1,db)+1,tname); - (void) hash_init(&hash_columns,&my_charset_latin1, + (void) hash_init(&hash_columns,system_charset_info, 0,0,0, (hash_get_key) get_key_column,0,0); } @@ -1911,7 +1912,8 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) if (!db || !tname) { /* Wrong table row; Ignore it */ - privs = cols = 0; /* purecov: inspected */ + hash_clear(&hash_columns); /* allow for destruction */ + privs= cols= 0; /* purecov: inspected */ return; /* purecov: inspected */ } if (lower_case_table_names) @@ -1928,16 +1930,16 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) privs = fix_rights_for_table(privs); cols = fix_rights_for_column(cols); - (void) hash_init(&hash_columns,&my_charset_latin1, + (void) hash_init(&hash_columns,system_charset_info, 0,0,0, (hash_get_key) get_key_column,0,0); if (cols) { int key_len; col_privs->field[0]->store(orig_host,(uint) strlen(orig_host), - &my_charset_latin1); - col_privs->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - col_privs->field[2]->store(user,(uint) strlen(user), &my_charset_latin1); - col_privs->field[3]->store(tname,(uint) strlen(tname), &my_charset_latin1); + system_charset_info); + col_privs->field[1]->store(db,(uint) strlen(db), system_charset_info); + col_privs->field[2]->store(user,(uint) strlen(user), system_charset_info); + col_privs->field[3]->store(tname,(uint) strlen(tname), system_charset_info); key_len=(col_privs->field[0]->pack_length()+ col_privs->field[1]->pack_length()+ col_privs->field[2]->pack_length()+ @@ -1975,6 +1977,12 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) } +GRANT_TABLE::~GRANT_TABLE() +{ + hash_free(&hash_columns); +} + + static byte* get_grant_table(GRANT_TABLE *buff,uint *length, my_bool not_used __attribute__((unused))) { @@ -2011,15 +2019,15 @@ static GRANT_TABLE *table_hash_search(const char *host,const char* ip, if (exact) { if ((host && - !my_strcasecmp(&my_charset_latin1, host, grant_table->host)) || + !my_strcasecmp(system_charset_info, host, grant_table->host)) || (ip && !strcmp(ip,grant_table->host))) return grant_table; } else { - if (((host && !wild_case_compare(&my_charset_latin1, + if (((host && !wild_case_compare(system_charset_info, host,grant_table->host)) || - (ip && !wild_case_compare(&my_charset_latin1, + (ip && !wild_case_compare(system_charset_info, ip,grant_table->host))) && (!found || found->sort < grant_table->sort)) found=grant_table; // Host ok @@ -2048,10 +2056,10 @@ static int replace_column_table(GRANT_TABLE *g_t, byte key[MAX_KEY_LENGTH]; DBUG_ENTER("replace_column_table"); - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); key_length=(table->field[0]->pack_length()+ table->field[1]->pack_length()+ table->field[2]->pack_length()+ table->field[3]->pack_length()); key_copy(key,table->record[0],table->key_info,key_length); @@ -2069,7 +2077,7 @@ static int replace_column_table(GRANT_TABLE *g_t, bool old_row_exists=0; key_restore(table->record[0],key,table->key_info,key_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), - &my_charset_latin1); + system_charset_info); table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read(table->record[0],(byte*) table->field[0]->ptr, @@ -2088,7 +2096,7 @@ static int replace_column_table(GRANT_TABLE *g_t, restore_record(table,default_values); // Get empty record key_restore(table->record[0],key,table->key_info,key_length); table->field[4]->store(xx->column.ptr(),xx->column.length(), - &my_charset_latin1); + system_charset_info); } else { @@ -2160,7 +2168,7 @@ static int replace_column_table(GRANT_TABLE *g_t, { GRANT_COLUMN *grant_column = NULL; char colum_name_buf[HOSTNAME_LENGTH+1]; - String column_name(colum_name_buf,sizeof(colum_name_buf),&my_charset_latin1); + String column_name(colum_name_buf,sizeof(colum_name_buf),system_charset_info); privileges&= ~rights; table->field[6]->store((longlong) @@ -2231,10 +2239,10 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } restore_record(table,default_values); // Get empty record - table->field[0]->store(combo.host.str,combo.host.length, &my_charset_latin1); - table->field[1]->store(db,(uint) strlen(db), &my_charset_latin1); - table->field[2]->store(combo.user.str,combo.user.length, &my_charset_latin1); - table->field[3]->store(table_name,(uint) strlen(table_name), &my_charset_latin1); + table->field[0]->store(combo.host.str,combo.host.length, system_charset_info); + table->field[1]->store(db,(uint) strlen(db), system_charset_info); + table->field[2]->store(combo.user.str,combo.user.length, system_charset_info); + table->field[3]->store(table_name,(uint) strlen(table_name), system_charset_info); store_record(table,record[1]); // store at pos 1 table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); if (table->file->index_read_idx(table->record[0],0, @@ -2279,7 +2287,7 @@ static int replace_table_table(THD *thd, GRANT_TABLE *grant_table, } } - table->field[4]->store(grantor,(uint) strlen(grantor), &my_charset_latin1); + table->field[4]->store(grantor,(uint) strlen(grantor), system_charset_info); table->field[6]->store((longlong) store_table_rights); table->field[7]->store((longlong) store_col_rights); rights=fix_rights_for_table(store_table_rights); @@ -2694,7 +2702,7 @@ my_bool grant_init(THD *org_thd) DBUG_ENTER("grant_init"); grant_option = FALSE; - (void) hash_init(&column_priv_hash,&my_charset_latin1, + (void) hash_init(&column_priv_hash,system_charset_info, 0,0,0, (hash_get_key) get_grant_table, (hash_free_key) free_grant_table,0); init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); @@ -2759,8 +2767,11 @@ my_bool grant_init(THD *org_thd) } } - if (mem_check->ok() && my_hash_insert(&column_priv_hash,(byte*) mem_check)) + if (! mem_check->ok()) + delete mem_check; + else if (my_hash_insert(&column_priv_hash,(byte*) mem_check)) { + delete mem_check; grant_option= FALSE; goto end_unlock; } @@ -3077,9 +3088,9 @@ bool check_grant_db(THD *thd,const char *db) idx); if (len < grant_table->key_length && !memcmp(grant_table->hash_key,helping,len) && - (thd->host && !wild_case_compare(&my_charset_latin1, + (thd->host && !wild_case_compare(system_charset_info, thd->host,grant_table->host) || - (thd->ip && !wild_case_compare(&my_charset_latin1, + (thd->ip && !wild_case_compare(system_charset_info, thd->ip,grant_table->host)))) { error=0; // Found match @@ -3230,7 +3241,7 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) if (!(host=acl_user->host.hostname)) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) break; } if (counter == acl_users.elements) @@ -3284,7 +3295,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append(lex_user->user.str, lex_user->user.length, system_charset_info); global.append ("'@'",3); - global.append(lex_user->host.str,lex_user->host.length); + global.append(lex_user->host.str,lex_user->host.length, + system_charset_info); global.append ('\''); if (acl_user->salt_len) { @@ -3318,7 +3330,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) if (ssl_options++) global.append(' '); global.append("SUBJECT \'",9); - global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); + global.append(acl_user->x509_subject,strlen(acl_user->x509_subject), + system_charset_info); global.append('\''); } if (acl_user->ssl_cipher) @@ -3326,7 +3339,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) if (ssl_options++) global.append(' '); global.append("CIPHER '",8); - global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher)); + global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher), + system_charset_info); global.append('\''); } } @@ -3365,7 +3379,7 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) host= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, host)) + !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { want_access=acl_db->access; if (want_access) @@ -3399,7 +3413,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) db.append(lex_user->user.str, lex_user->user.length, system_charset_info); db.append ("'@'",3); - db.append(lex_user->host.str, lex_user->host.length); + db.append(lex_user->host.str, lex_user->host.length, + system_charset_info); db.append ('\''); if (want_access & GRANT_ACL) db.append(" WITH GRANT OPTION",18); @@ -3425,7 +3440,7 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) user= ""; if (!strcmp(lex_user->user.str,user) && - !my_strcasecmp(&my_charset_latin1, lex_user->host.str, + !my_strcasecmp(system_charset_info, lex_user->host.str, grant_table->orig_host)) { ulong table_access= grant_table->privs; @@ -3505,7 +3520,8 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append(lex_user->user.str, lex_user->user.length, system_charset_info); global.append("'@'",3); - global.append(lex_user->host.str,lex_user->host.length); + global.append(lex_user->host.str,lex_user->host.length, + system_charset_info); global.append('\''); if (table_access & GRANT_ACL) global.append(" WITH GRANT OPTION",18); @@ -3565,6 +3581,27 @@ void get_mqh(const char *user, const char *host, USER_CONN *uc) bzero((char*) &uc->user_resources, sizeof(uc->user_resources)); } +/* + Open the grant tables. + + SYNOPSIS + open_grant_tables() + thd The current thread. + tables (out) The 4 elements array for the opened tables. + + DESCRIPTION + Tables are numbered as follows: + 0 user + 1 db + 2 tables_priv + 3 columns_priv + + RETURN + 1 Skip GRANT handling during replication. + 0 OK. + < 0 Error. +*/ + int open_grant_tables(THD *thd, TABLE_LIST *tables) { DBUG_ENTER("open_grant_tables"); @@ -3640,111 +3677,563 @@ ACL_USER *check_acl_user(LEX_USER *user_name, } -bool mysql_drop_user(THD *thd, List &list) +/* + Modify a privilege table. + + SYNOPSIS + modify_grant_table() + table The table to modify. + host_field The host name field. + user_field The user name field. + user_to The new name for the user if to be renamed, + NULL otherwise. + + DESCRIPTION + Update user/host in the current record if user_to is not NULL. + Delete the current record if user_to is NULL. + + RETURN + 0 OK. + != 0 Error. +*/ + +static int modify_grant_table(TABLE *table, Field *host_field, + Field *user_field, LEX_USER *user_to) { - uint counter, acl_userd; - int result; + int error; + DBUG_ENTER("modify_grant_table"); + + if (user_to) + { + /* rename */ + store_record(table, record[1]); + host_field->store(user_to->host.str, user_to->host.length, + system_charset_info); + user_field->store(user_to->user.str, user_to->user.length, + system_charset_info); + if ((error= table->file->update_row(table->record[1], table->record[0]))) + table->file->print_error(error, MYF(0)); + } + else + { + /* delete */ + if ((error=table->file->delete_row(table->record[0]))) + table->file->print_error(error, MYF(0)); + } + + DBUG_RETURN(error); +} + + +/* + Handle a privilege table. + + SYNOPSIS + handle_grant_table() + tables The array with the four open tables. + table_no The number of the table to handle (0..3). + drop If user_from is to be dropped. + user_from The the user to be searched/dropped/renamed. + user_to The new name for the user if to be renamed, + NULL otherwise. + + DESCRIPTION + Scan through all records in a grant table and apply the requested + operation. For the "user" table, a single index access is sufficient, + since there is an unique index on (host, user). + Delete from grant table if drop is true. + Update in grant table if drop is false and user_to is not NULL. + Search in grant table if drop is false and user_to is NULL. + Tables are numbered as follows: + 0 user + 1 db + 2 tables_priv + 3 columns_priv + + RETURN + > 0 At least one record matched. + 0 OK, but no record matched. + < 0 Error. +*/ + +static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop, + LEX_USER *user_from, LEX_USER *user_to) +{ + int result= 0; + int error; + TABLE *table= tables[table_no].table; + Field *host_field= table->field[0]; + Field *user_field= table->field[table_no ? 2 : 1]; + char *host_str= user_from->host.str; + char *user_str= user_from->user.str; + const char *host; + const char *user; + DBUG_ENTER("handle_grant_table"); + + if (! table_no) + { + /* + The 'user' table has an unique index on (host, user). + Thus, we can handle everything with a single index access. + The host- and user fields are consecutive in the user table records. + So we set host- and user fields of table->record[0] and use the + pointer to the host field as key. + index_read_idx() will replace table->record[0] (its first argument) + by the searched record, if it exists. + */ + DBUG_PRINT("info",("read table: '%s' search: '%s'@'%s'", + table->real_name, user_str, host_str)); + host_field->store(host_str, user_from->host.length, system_charset_info); + user_field->store(user_str, user_from->user.length, system_charset_info); + if ((error= table->file->index_read_idx(table->record[0], 0, + (byte*) host_field->ptr, 0, + HA_READ_KEY_EXACT))) + { + if (error != HA_ERR_KEY_NOT_FOUND) + { + table->file->print_error(error, MYF(0)); + result= -1; + } + } + else + { + /* If requested, delete or update the record. */ + result= ((drop || user_to) && + modify_grant_table(table, host_field, user_field, user_to)) ? + -1 : 1; /* Error or found. */ + } + DBUG_PRINT("info",("read result: %d", result)); + } + else + { + /* + The non-'user' table do not have indexes on (host, user). + And their host- and user fields are not consecutive. + Thus, we need to do a table scan to find all matching records. + */ + if ((error= table->file->ha_rnd_init(1))) + { + table->file->print_error(error, MYF(0)); + result= -1; + } + else + { +#ifdef EXTRA_DEBUG + DBUG_PRINT("info",("scan table: '%s' search: '%s'@'%s'", + table->real_name, user_str, host_str)); +#endif + while ((error= table->file->rnd_next(table->record[0])) != + HA_ERR_END_OF_FILE) + { + if (error) + { + /* Most probable 'deleted record'. */ + DBUG_PRINT("info",("scan error: %d", error)); + continue; + } + if (! (host= get_field(&mem, host_field))) + host= ""; + if (! (user= get_field(&mem, user_field))) + user= ""; + +#ifdef EXTRA_DEBUG + DBUG_PRINT("loop",("scan fields: '%s'@'%s' '%s' '%s' '%s'", + user, host, + get_field(&mem, table->field[1]) /*db*/, + get_field(&mem, table->field[3]) /*table*/, + get_field(&mem, table->field[4]) /*column*/)); +#endif + if (strcmp(user_str, user) || + my_strcasecmp(system_charset_info, host_str, host)) + continue; + + /* If requested, delete or update the record. */ + result= ((drop || user_to) && + modify_grant_table(table, host_field, user_field, user_to)) ? + -1 : result ? result : 1; /* Error or keep result or found. */ + /* If search is requested, we do not need to search further. */ + if (! drop && ! user_to) + break ; + } + (void) table->file->ha_rnd_end(); + DBUG_PRINT("info",("scan result: %d", result)); + } + } + + DBUG_RETURN(result); +} + + +/* + Handle an in-memory privilege structure. + + SYNOPSIS + handle_grant_struct() + struct_no The number of the structure to handle (0..2). + drop If user_from is to be dropped. + user_from The the user to be searched/dropped/renamed. + user_to The new name for the user if to be renamed, + NULL otherwise. + + DESCRIPTION + Scan through all elements in an in-memory grant structure and apply + the requested operation. + Delete from grant structure if drop is true. + Update in grant structure if drop is false and user_to is not NULL. + Search in grant structure if drop is false and user_to is NULL. + Structures are numbered as follows: + 0 acl_users + 1 acl_dbs + 2 column_priv_hash + + RETURN + > 0 At least one element matched. + 0 OK, but no element matched. +*/ + +static int handle_grant_struct(uint struct_no, bool drop, + LEX_USER *user_from, LEX_USER *user_to) +{ + int result= 0; + uint idx; + uint elements; + const char *user; + const char *host; ACL_USER *acl_user; ACL_DB *acl_db; + GRANT_TABLE *grant_table; + DBUG_ENTER("handle_grant_struct"); + LINT_INIT(acl_user); + LINT_INIT(acl_db); + LINT_INIT(grant_table); + DBUG_PRINT("info",("scan struct: %u search: '%s'@'%s'", + struct_no, user_from->user.str, user_from->host.str)); + + /* Get the number of elements in the in-memory structure. */ + switch (struct_no) + { + case 0: + elements= acl_users.elements; + break; + case 1: + elements= acl_dbs.elements; + break; + default: + elements= column_priv_hash.records; + } + +#ifdef EXTRA_DEBUG + DBUG_PRINT("loop",("scan struct: %u search user: '%s' host: '%s'", + struct_no, user_from->user.str, user_from->host.str)); +#endif + /* Loop over all elements. */ + for (idx= 0; idx < elements; idx++) + { + /* + Get a pointer to the element. + Unfortunaltely, the host default differs for the structures. + */ + switch (struct_no) + { + case 0: + acl_user= dynamic_element(&acl_users, idx, ACL_USER*); + user= acl_user->user; + if (!(host= acl_user->host.hostname)) + host= "%"; + break; + + case 1: + acl_db= dynamic_element(&acl_dbs, idx, ACL_DB*); + user= acl_db->user; + host= acl_db->host.hostname; + break; + + default: + grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash, idx); + user= grant_table->user; + host= grant_table->host; + } + if (! user) + user= ""; + if (! host) + host= ""; +#ifdef EXTRA_DEBUG + DBUG_PRINT("loop",("scan struct: %u index: %u user: '%s' host: '%s'", + struct_no, idx, user, host)); +#endif + if (strcmp(user_from->user.str, user) || + my_strcasecmp(system_charset_info, user_from->host.str, host)) + continue; + + result= 1; /* At least one element found. */ + if ( drop ) + { + switch ( struct_no ) + { + case 0: + delete_dynamic_element(&acl_users, idx); + break; + + case 1: + delete_dynamic_element(&acl_dbs, idx); + break; + + default: + hash_delete(&column_priv_hash, (byte*) grant_table); + } + elements--; + idx--; + } + else if ( user_to ) + { + switch ( struct_no ) + { + case 0: + acl_user->user= strdup_root(&mem, user_to->user.str); + acl_user->host.hostname= strdup_root(&mem, user_to->host.str); + break; + + case 1: + acl_db->user= strdup_root(&mem, user_to->user.str); + acl_db->host.hostname= strdup_root(&mem, user_to->host.str); + break; + + default: + grant_table->user= strdup_root(&mem, user_to->user.str); + grant_table->host= strdup_root(&mem, user_to->host.str); + } + } + else + { + /* If search is requested, we do not need to search further. */ + break; + } + } +#ifdef EXTRA_DEBUG + DBUG_PRINT("loop",("scan struct: %u result %d", struct_no, result)); +#endif + + DBUG_RETURN(result); +} + + +/* + Handle all privilege tables and in-memory privilege structures. + + SYNOPSIS + handle_grant_data() + tables The array with the four open tables. + drop If user_from is to be dropped. + user_from The the user to be searched/dropped/renamed. + user_to The new name for the user if to be renamed, + NULL otherwise. + + DESCRIPTION + Go through all grant tables and in-memory grant structures and apply + the requested operation. + Delete from grant data if drop is true. + Update in grant data if drop is false and user_to is not NULL. + Search in grant data if drop is false and user_to is NULL. + + RETURN + > 0 At least one element matched. + 0 OK, but no element matched. + < 0 Error. +*/ + +static int handle_grant_data(TABLE_LIST *tables, bool drop, + LEX_USER *user_from, LEX_USER *user_to) +{ + int result= 0; + int found; + DBUG_ENTER("handle_grant_data"); + + /* Handle user table. */ + if ((found= handle_grant_table(tables, 0, drop, user_from, user_to)) < 0) + { + /* Handle of table failed, don't touch the in-memory array. */ + result= -1; + } + else + { + /* Handle user array. */ + if ((handle_grant_struct(0, drop, user_from, user_to) && ! result) || found) + { + result= 1; /* At least one record/element found. */ + /* If search is requested, we do not need to search further. */ + if (! drop && ! user_to) + goto end; + } + } + + /* Handle db table. */ + if ((found= handle_grant_table(tables, 1, drop, user_from, user_to)) < 0) + { + /* Handle of table failed, don't touch the in-memory array. */ + result= -1; + } + else + { + /* Handle db array. */ + if (((handle_grant_struct(1, drop, user_from, user_to) && ! result) || + found) && ! result) + { + result= 1; /* At least one record/element found. */ + /* If search is requested, we do not need to search further. */ + if (! drop && ! user_to) + goto end; + } + } + + /* Handle tables table. */ + if ((found= handle_grant_table(tables, 2, drop, user_from, user_to)) < 0) + { + /* Handle of table failed, don't touch columns and in-memory array. */ + result= -1; + } + else + { + if (found && ! result) + { + result= 1; /* At least one record found. */ + /* If search is requested, we do not need to search further. */ + if (! drop && ! user_to) + goto end; + } + + /* Handle columns table. */ + if ((found= handle_grant_table(tables, 3, drop, user_from, user_to)) < 0) + { + /* Handle of table failed, don't touch the in-memory array. */ + result= -1; + } + else + { + /* Handle columns hash. */ + if (((handle_grant_struct(2, drop, user_from, user_to) && ! result) || + found) && ! result) + result= 1; /* At least one record/element found. */ + } + } + end: + DBUG_RETURN(result); +} + + +/* + Create a list of users. + + SYNOPSIS + mysql_create_user() + thd The current thread. + list The users to create. + + RETURN + FALSE OK. + TRUE Error. +*/ + +bool mysql_create_user(THD *thd, List &list) +{ + int result; + int found; + uint failures; + ulong sql_mode; + LEX_USER *user_name; + List_iterator user_list(list); TABLE_LIST tables[4]; + DBUG_ENTER("mysql_create_user"); - DBUG_ENTER("mysql_drop_user"); - + /* CREATE USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) DBUG_RETURN(result != 1); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); + failures= 0; + while ((user_name= user_list++)) + { + /* + Search all in-memory structures and grant tables + for a mention of the new user name. + */ + if ((found= handle_grant_data(tables, 0, user_name, NULL))) + { + if (found > 0) + sql_print_error("CREATE USER: Cannot create user: '%s'@'%s': " + "User exists", + user_name->user.str, + user_name->host.str); + failures++; + result= TRUE; + } + + sql_mode= thd->variables.sql_mode; + thd->variables.sql_mode&= ~MODE_NO_AUTO_CREATE_USER; + if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1)) + { + failures++; + result= TRUE; + } + thd->variables.sql_mode= sql_mode; + } + + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); + close_thread_tables(thd); + if (result) + my_error(ER_HANDLE_USER, MYF(0), "CREATE USER" , failures ); + DBUG_RETURN(result); +} + + +/* + Drop a list of users and all their privileges. + + SYNOPSIS + mysql_drop_user() + thd The current thread. + list The users to drop. + + RETURN + FALSE OK. + TRUE Error. +*/ + +bool mysql_drop_user(THD *thd, List &list) +{ + int result; + int found; + uint failures; LEX_USER *user_name; List_iterator user_list(list); - while ((user_name=user_list++)) + TABLE_LIST tables[4]; + DBUG_ENTER("mysql_drop_user"); + + /* CREATE USER may be skipped on replication client. */ + if ((result= open_grant_tables(thd, tables))) + DBUG_RETURN(result != 1); + + rw_wrlock(&LOCK_grant); + VOID(pthread_mutex_lock(&acl_cache->lock)); + + failures= 0; + while ((user_name= user_list++)) { - if (!(acl_user= check_acl_user(user_name, &counter))) + if ((found= handle_grant_data(tables, 1, user_name, NULL)) < 0) { - sql_print_error("DROP USER: Can't drop user: '%s'@'%s'; No such user", - user_name->user.str, - user_name->host.str); - result= -1; - continue; + failures++; + result= TRUE; } - if ((acl_user->access & ~0)) + else if (! found) { - sql_print_error("DROP USER: Can't drop user: '%s'@'%s'; Global privileges exists", - user_name->user.str, - user_name->host.str); - result= -1; - continue; - } - acl_userd= counter; - - for (counter= 0 ; counter < acl_dbs.elements ; counter++) - { - const char *user,*host; - acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); - if (!(user= acl_db->user)) - user= ""; - if (!(host= acl_db->host.hostname)) - host= ""; - - if (!strcmp(user_name->user.str,user) && - !my_strcasecmp(system_charset_info, user_name->host.str, host)) - break; - } - if (counter != acl_dbs.elements) - { - sql_print_error("DROP USER: Can't drop user: '%s'@'%s'; Database privileges exists", - user_name->user.str, - user_name->host.str); - result= -1; - continue; - } - - for (counter= 0 ; counter < column_priv_hash.records ; counter++) - { - const char *user,*host; - GRANT_TABLE *grant_table= (GRANT_TABLE*) hash_element(&column_priv_hash, - counter); - if (!(user=grant_table->user)) - user= ""; - if (!(host=grant_table->host)) - host= ""; - - if (!strcmp(user_name->user.str,user) && - !my_strcasecmp(system_charset_info, user_name->host.str, host)) - break; - } - if (counter != column_priv_hash.records) - { - sql_print_error("DROP USER: Can't drop user: '%s'@'%s'; Table privileges exists", - user_name->user.str, - user_name->host.str); - result= -1; - continue; - } - - tables[0].table->field[0]->store(user_name->host.str,(uint) - user_name->host.length, - system_charset_info); - tables[0].table->field[1]->store(user_name->user.str,(uint) - user_name->user.length, - system_charset_info); - tables[0].table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS); - if (!tables[0].table->file->index_read_idx(tables[0].table->record[0],0, - (byte*) tables[0].table-> - field[0]->ptr, - tables[0].table-> - key_info[0].key_length, - HA_READ_KEY_EXACT)) - { - int error; - if ((error = tables[0].table->file->delete_row(tables[0].table-> - record[0]))) - { - tables[0].table->file->print_error(error, MYF(0)); - DBUG_RETURN(TRUE); - } - delete_dynamic_element(&acl_users, acl_userd); + sql_print_error("DROP USER: Cannot drop user '%s'@'%s': " + "No such user", + user_name->user.str, + user_name->host.str); + failures++; + result= TRUE; } } @@ -3752,10 +4241,102 @@ bool mysql_drop_user(THD *thd, List &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) - my_message(ER_DROP_USER, ER(ER_DROP_USER), MYF(0)); + my_error(ER_HANDLE_USER, MYF(0), "DROP USER" , failures ); DBUG_RETURN(result); } + +/* + Rename a user. + + SYNOPSIS + mysql_rename_user() + thd The current thread. + list The user name pairs: (from, to). + + RETURN + FALSE OK. + TRUE Error. +*/ + +bool mysql_rename_user(THD *thd, List &list) +{ + int result= 0; + int found; + uint failures; + LEX_USER *user_from; + LEX_USER *user_to; + List_iterator user_list(list); + TABLE_LIST tables[4]; + DBUG_ENTER("mysql_rename_user"); + + /* CREATE USER may be skipped on replication client. */ + if ((result= open_grant_tables(thd, tables))) + DBUG_RETURN(result != 1); + + rw_wrlock(&LOCK_grant); + VOID(pthread_mutex_lock(&acl_cache->lock)); + + failures= 0; + while ((user_from= user_list++)) + { + user_to= user_list++; + DBUG_ASSERT((user_to)); /* Syntax enforces pairs of users. */ + + /* + Search all in-memory structures and grant tables + for a mention of the new user name. + */ + if ((found= handle_grant_data(tables, 0, user_to, NULL))) + { + if (found > 0) + sql_print_error("RENAME USER: Cannot rename to: '%s'@'%s': User exists", + user_to->user.str, + user_to->host.str); + failures++; + result= TRUE; + } + else + { + if ((found= handle_grant_data(tables, 0, user_from, user_to)) < 0) + { + failures++; + result= TRUE; + } + else if (! found) + { + sql_print_error("RENAME USER: Cannot rename user: '%s'@'%s': " + "No such user", + user_from->user.str, + user_from->host.str); + failures++; + result= TRUE; + } + } + } + + VOID(pthread_mutex_unlock(&acl_cache->lock)); + rw_unlock(&LOCK_grant); + close_thread_tables(thd); + if (result) + my_error(ER_HANDLE_USER, MYF(0), "RENAME USER", failures); + DBUG_RETURN(result); +} + +/* + Revoke all privileges from a list of users. + + SYNOPSIS + mysql_revoke_all() + thd The current thread. + list The users to revoke all privileges from. + + RETURN + > 0 Error. Error message already sent. + 0 OK. + < 0 Error. Error message not yet sent. +*/ + bool mysql_revoke_all(THD *thd, List &list) { uint counter, revoked; diff --git a/sql/sql_acl.h b/sql/sql_acl.h index f6074da5279..8f3ee072f43 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -182,7 +182,9 @@ ulong get_column_grant(THD *thd, GRANT_INFO *grant, bool mysql_show_grants(THD *thd, LEX_USER *user); void get_privilege_desc(char *to, uint max_length, ulong access); void get_mqh(const char *user, const char *host, USER_CONN *uc); +bool mysql_create_user(THD *thd, List &list); bool mysql_drop_user(THD *thd, List &list); +bool mysql_rename_user(THD *thd, List &list); bool mysql_revoke_all(THD *thd, List &list); void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant, const char *db, const char *table); diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 605204fe35d..e911b0ad4d1 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -78,7 +78,8 @@ enum enum_sql_command { SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, SQLCOM_DO, SQLCOM_SHOW_WARNS, SQLCOM_EMPTY_QUERY, SQLCOM_SHOW_ERRORS, SQLCOM_SHOW_COLUMN_TYPES, SQLCOM_SHOW_STORAGE_ENGINES, SQLCOM_SHOW_PRIVILEGES, - SQLCOM_HELP, SQLCOM_DROP_USER, SQLCOM_REVOKE_ALL, SQLCOM_CHECKSUM, + SQLCOM_HELP, SQLCOM_CREATE_USER, SQLCOM_DROP_USER, SQLCOM_RENAME_USER, + SQLCOM_REVOKE_ALL, SQLCOM_CHECKSUM, SQLCOM_CREATE_PROCEDURE, SQLCOM_CREATE_SPFUNCTION, SQLCOM_CALL, SQLCOM_DROP_PROCEDURE, SQLCOM_ALTER_PROCEDURE,SQLCOM_ALTER_FUNCTION, SQLCOM_SHOW_CREATE_PROC, SQLCOM_SHOW_CREATE_FUNC, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index fce8d294456..2dba134f54e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3370,6 +3370,21 @@ create_error: break; } #ifndef NO_EMBEDDED_ACCESS_CHECKS + case SQLCOM_CREATE_USER: + { + if (check_access(thd, GRANT_ACL,"mysql",0,1,0)) + break; + if (!(res= mysql_create_user(thd, lex->users_list))) + { + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + mysql_bin_log.write(&qinfo); + } + send_ok(thd); + } + break; + } case SQLCOM_DROP_USER: { if (check_access(thd, GRANT_ACL,"mysql",0,1,0)) @@ -3378,8 +3393,23 @@ create_error: { if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0); - mysql_bin_log.write(&qinfo); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + mysql_bin_log.write(&qinfo); + } + send_ok(thd); + } + break; + } + case SQLCOM_RENAME_USER: + { + if (check_access(thd, GRANT_ACL,"mysql",0,1,0)) + break; + if (!(res= mysql_rename_user(thd, lex->users_list))) + { + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + mysql_bin_log.write(&qinfo); } send_ok(thd); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index dd9cd4af0f3..8e9b649acc3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -788,9 +788,9 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); opt_delete_options opt_delete_option varchar nchar nvarchar opt_outer table_list table_name opt_option opt_place opt_attribute opt_attribute_list attribute column_list column_list_id - opt_column_list grant_privileges opt_table user_list grant_option - grant_privilege grant_privilege_list - flush_options flush_option + opt_column_list grant_privileges opt_table grant_list grant_option + grant_privilege grant_privilege_list user_list rename_list + clear_privileges flush_options flush_option equal optional_braces opt_key_definition key_usage_list2 opt_mi_check_type opt_to mi_check_types normal_join table_to_table_list table_to_table opt_table_list opt_as @@ -1287,8 +1287,26 @@ create: TL_WRITE)) YYABORT; } + | CREATE USER clear_privileges grant_list + { + Lex->sql_command = SQLCOM_CREATE_USER; + } ; +clear_privileges: + /* Nothing */ + { + LEX *lex=Lex; + lex->users_list.empty(); + lex->columns.empty(); + lex->grant= lex->grant_tot_col= 0; + lex->select_lex.db= 0; + lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; + lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; + bzero((char *)&(lex->mqh),sizeof(lex->mqh)); + } + ; + sp_name: IDENT_sys '.' IDENT_sys { @@ -3671,8 +3689,25 @@ rename: } table_to_table_list {} + | RENAME USER clear_privileges rename_list + { + Lex->sql_command = SQLCOM_RENAME_USER; + } ; +rename_list: + user TO_SYM user + { + if (Lex->users_list.push_back($1) || Lex->users_list.push_back($3)) + YYABORT; + } + | rename_list ',' user TO_SYM user + { + if (Lex->users_list.push_back($3) || Lex->users_list.push_back($5)) + YYABORT; + } + ; + table_to_table_list: table_to_table | table_to_table_list ',' table_to_table; @@ -5479,14 +5514,10 @@ drop: lex->drop_if_exists= $3; lex->spname= $4; } - | DROP USER + | DROP USER clear_privileges user_list { - LEX *lex=Lex; - lex->sql_command = SQLCOM_DROP_USER; - lex->users_list.empty(); - } - user_list - {} + Lex->sql_command = SQLCOM_DROP_USER; + } | DROP VIEW_SYM if_exists table_list opt_restrict { THD *thd= YYTHD; @@ -7478,48 +7509,28 @@ handler_rkey_mode: /* GRANT / REVOKE */ revoke: - REVOKE - { - LEX *lex=Lex; - lex->sql_command = SQLCOM_REVOKE; - lex->users_list.empty(); - lex->columns.empty(); - lex->grant= lex->grant_tot_col=0; - lex->select_lex.db=0; - lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; - lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; - bzero((char*) &lex->mqh, sizeof(lex->mqh)); - } - revoke_command + REVOKE clear_privileges revoke_command {} ; revoke_command: - grant_privileges ON opt_table FROM user_list - {} + grant_privileges ON opt_table FROM grant_list + { + Lex->sql_command = SQLCOM_REVOKE; + } | - ALL opt_privileges ',' GRANT OPTION FROM user_list + ALL opt_privileges ',' GRANT OPTION FROM grant_list { Lex->sql_command = SQLCOM_REVOKE_ALL; } ; grant: - GRANT - { - LEX *lex=Lex; - lex->users_list.empty(); - lex->columns.empty(); - lex->sql_command = SQLCOM_GRANT; - lex->grant= lex->grant_tot_col= 0; - lex->select_lex.db= 0; - lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; - lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; - bzero((char *)&(lex->mqh),sizeof(lex->mqh)); - } - grant_privileges ON opt_table TO_SYM user_list + GRANT clear_privileges grant_privileges ON opt_table TO_SYM grant_list require_clause grant_options - {} + { + Lex->sql_command = SQLCOM_GRANT; + } ; grant_privileges: @@ -7659,8 +7670,18 @@ opt_table: user_list: + user { if (Lex->users_list.push_back($1)) YYABORT;} + | user_list ',' user + { + if (Lex->users_list.push_back($3)) + YYABORT; + } + ; + + +grant_list: grant_user { if (Lex->users_list.push_back($1)) YYABORT;} - | user_list ',' grant_user + | grant_list ',' grant_user { if (Lex->users_list.push_back($3)) YYABORT; From e67586b3d135934c349235a19348c06beec2132c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Nov 2004 23:57:58 +0300 Subject: [PATCH 08/38] Fix for the unixware: non-posix sigwait server-tools/instance-manager/manager.cc: Use my_sigwait instead of sigwait --- server-tools/instance-manager/manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc index 06e181d52d5..2690f882e04 100644 --- a/server-tools/instance-manager/manager.cc +++ b/server-tools/instance-manager/manager.cc @@ -56,7 +56,7 @@ void manager(const char *socket_file_name) in the process. */ int signo; - sigwait(&mask, &signo); + my_sigwait(&mask, &signo); thread_repository.deliver_shutdown(); /* don't pthread_exit to kill all threads who did not shut down in time */ } From 00534590af2c4bd9b6ab5bd068f381b12676fb49 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Nov 2004 21:29:59 +0000 Subject: [PATCH 09/38] moved default setting to config.ini to MgmtSrvr only try to connect to other ndb_mgmd if connect_string explicitly given or config_file not given ndb/src/mgmsrv/main.cpp: moved default setting to config.ini to MgmtSrvr --- ndb/src/mgmsrv/MgmtSrvr.cpp | 11 ++++++++--- ndb/src/mgmsrv/main.cpp | 1 - 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 81b5eb9dfb3..986da71a8e8 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -432,15 +432,20 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, theFacade = 0; m_newConfig = NULL; - m_configFilename.assign(config_filename); + if (config_filename) + m_configFilename.assign(config_filename); + else + m_configFilename.assign("config.ini"); m_nextConfigGenerationNumber = 0; m_config_retriever= new ConfigRetriever(connect_string, NDB_VERSION, NDB_MGM_NODE_TYPE_MGM); - + // if connect_string explicitly given or + // no config filename is given then // first try to allocate nodeid from another management server - if(m_config_retriever->do_connect(0,0,0) == 0) + if ((connect_string || config_filename == NULL) && + (m_config_retriever->do_connect(0,0,0) == 0)) { int tmp_nodeid= 0; tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/); diff --git a/ndb/src/mgmsrv/main.cpp b/ndb/src/mgmsrv/main.cpp index 1ab8cc0635e..400a5301a19 100644 --- a/ndb/src/mgmsrv/main.cpp +++ b/ndb/src/mgmsrv/main.cpp @@ -188,7 +188,6 @@ int main(int argc, char** argv) #endif global_mgmt_server_check = 1; - glob.config_filename= "config.ini"; const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 }; load_defaults("my",load_default_groups,&argc,&argv); From a560f0fa3888902e14378d3f8ee4416d2e1eab3b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 00:12:50 +0200 Subject: [PATCH 10/38] Many files: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/buf/buf0buf.c: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/buf/buf0lru.c: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/include/buf0lru.h: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/include/db0err.h: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/include/row0sel.h: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/include/ut0mem.h: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/mem/mem0pool.c: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/row/row0mysql.c: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/row/row0sel.c: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/srv/srv0start.c: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup innobase/ut/ut0mem.c: Fix bug #6817 and bug #6827 : do not crash the server if the buffer pool becomes filled by the locks of ONE huge transaction, return error 1206 instead; do not crash the server, but return error if we cannot allocate memory for the buffer pool at a mysqld startup --- innobase/buf/buf0buf.c | 5 +++-- innobase/buf/buf0lru.c | 41 ++++++++++++++++++++++++++++++++++---- innobase/include/buf0lru.h | 10 ++++++++++ innobase/include/db0err.h | 6 +++++- innobase/include/row0sel.h | 1 + innobase/include/ut0mem.h | 4 +++- innobase/mem/mem0pool.c | 2 +- innobase/row/row0mysql.c | 3 ++- innobase/row/row0sel.c | 11 ++++++++++ innobase/srv/srv0start.c | 3 +++ innobase/ut/ut0mem.c | 20 +++++++++++++------ 11 files changed, 90 insertions(+), 16 deletions(-) diff --git a/innobase/buf/buf0buf.c b/innobase/buf/buf0buf.c index adb69f3c3a7..699ad5fb42e 100644 --- a/innobase/buf/buf0buf.c +++ b/innobase/buf/buf0buf.c @@ -547,8 +547,9 @@ buf_pool_init( } /*----------------------------------------*/ } else { - buf_pool->frame_mem = ut_malloc( - UNIV_PAGE_SIZE * (n_frames + 1)); + buf_pool->frame_mem = ut_malloc_low( + UNIV_PAGE_SIZE * (n_frames + 1), + TRUE, FALSE); } if (buf_pool->frame_mem == NULL) { diff --git a/innobase/buf/buf0lru.c b/innobase/buf/buf0lru.c index 796311f0157..f3fb19ae183 100644 --- a/innobase/buf/buf0lru.c +++ b/innobase/buf/buf0lru.c @@ -42,6 +42,10 @@ initial segment in buf_LRU_get_recent_limit */ #define BUF_LRU_INITIAL_RATIO 8 +/* If we switch on the InnoDB monitor because there are too few available +frames in the buffer pool, we set this to TRUE */ +ibool buf_lru_switched_on_innodb_mon = FALSE; + /********************************************************************** Takes a block out of the LRU list and page hash table and sets the block state to BUF_BLOCK_REMOVE_HASH. */ @@ -287,6 +291,32 @@ buf_LRU_try_free_flushed_blocks(void) mutex_exit(&(buf_pool->mutex)); } +/********************************************************************** +Returns TRUE if less than 15 % of the buffer pool is available. This can be +used in heuristics to prevent huge transactions eating up the whole buffer +pool for their locks. */ + +ibool +buf_LRU_buf_pool_running_out(void) +/*==============================*/ + /* out: TRUE if less than 15 % of buffer pool + left */ +{ + ibool ret = FALSE; + + mutex_enter(&(buf_pool->mutex)); + + if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) + + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 7) { + + ret = TRUE; + } + + mutex_exit(&(buf_pool->mutex)); + + return(ret); +} + /********************************************************************** Returns a free block from buf_pool. The block is taken off the free list. If it is empty, blocks are moved from the end of the LRU list to the free @@ -325,7 +355,8 @@ loop: } else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) { - if (!srv_print_innodb_monitor) { + + if (!buf_lru_switched_on_innodb_mon) { /* Over 80 % of the buffer pool is occupied by lock heaps or the adaptive hash index. This may be a memory @@ -342,16 +373,18 @@ loop: "InnoDB: lock heap and hash index sizes.\n", (ulong) (buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE))); + buf_lru_switched_on_innodb_mon = TRUE; srv_print_innodb_monitor = TRUE; os_event_set(srv_lock_timeout_thread_event); } - } else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) - + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) { + } else if (buf_lru_switched_on_innodb_mon) { /* Switch off the InnoDB Monitor; this is a simple way to stop the monitor if the situation becomes less urgent, - but may also surprise users! */ + but may also surprise users if the user also switched on the + monitor! */ + buf_lru_switched_on_innodb_mon = FALSE; srv_print_innodb_monitor = FALSE; } diff --git a/innobase/include/buf0lru.h b/innobase/include/buf0lru.h index 69a376f8cab..45164dd561e 100644 --- a/innobase/include/buf0lru.h +++ b/innobase/include/buf0lru.h @@ -25,6 +25,16 @@ wasted. */ void buf_LRU_try_free_flushed_blocks(void); /*==================================*/ +/********************************************************************** +Returns TRUE if less than 15 % of the buffer pool is available. This can be +used in heuristics to prevent huge transactions eating up the whole buffer +pool for their locks. */ + +ibool +buf_LRU_buf_pool_running_out(void); +/*==============================*/ + /* out: TRUE if less than 15 % of buffer pool + left */ /*####################################################################### These are low-level functions diff --git a/innobase/include/db0err.h b/innobase/include/db0err.h index be7667bfd0c..de5ac44e73f 100644 --- a/innobase/include/db0err.h +++ b/innobase/include/db0err.h @@ -53,7 +53,11 @@ Created 5/24/1996 Heikki Tuuri name already exists */ #define DB_TABLESPACE_DELETED 44 /* tablespace does not exist or is being dropped right now */ - +#define DB_LOCK_TABLE_FULL 45 /* lock structs have exhausted the + buffer pool (for big transactions, + InnoDB stores the lock structs in the + buffer pool) */ + /* The following are partial failure codes */ #define DB_FAIL 1000 #define DB_OVERFLOW 1001 diff --git a/innobase/include/row0sel.h b/innobase/include/row0sel.h index bb6fb70ca86..8d5187bfc1c 100644 --- a/innobase/include/row0sel.h +++ b/innobase/include/row0sel.h @@ -120,6 +120,7 @@ row_search_for_mysql( /* out: DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK, + DB_LOCK_TABLE_FULL, or DB_TOO_BIG_RECORD */ byte* buf, /* in/out: buffer for the fetched row in the MySQL format */ diff --git a/innobase/include/ut0mem.h b/innobase/include/ut0mem.h index 73ecb25101a..74357f6bf13 100644 --- a/innobase/include/ut0mem.h +++ b/innobase/include/ut0mem.h @@ -38,8 +38,10 @@ ut_malloc_low( /*==========*/ /* out, own: allocated memory */ ulint n, /* in: number of bytes to allocate */ - ibool set_to_zero); /* in: TRUE if allocated memory should be set + ibool set_to_zero, /* in: TRUE if allocated memory should be set to zero if UNIV_SET_MEM_TO_ZERO is defined */ + ibool assert_on_error); /* in: if TRUE, we crash mysqld if the memory + cannot be allocated */ /************************************************************************** Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is defined. */ diff --git a/innobase/mem/mem0pool.c b/innobase/mem/mem0pool.c index 023369e8ec5..cb891a03092 100644 --- a/innobase/mem/mem0pool.c +++ b/innobase/mem/mem0pool.c @@ -199,7 +199,7 @@ mem_pool_create( but only when allocated at a higher level in mem0mem.c. This is to avoid masking useful Purify warnings. */ - pool->buf = ut_malloc_low(size, FALSE); + pool->buf = ut_malloc_low(size, FALSE, TRUE); pool->size = size; mutex_create(&(pool->mutex)); diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 17747ae2a8e..9613da2e286 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -308,7 +308,8 @@ handle_new_error: return(TRUE); - } else if (err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT) { + } else if (err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT + || err == DB_LOCK_TABLE_FULL) { /* Roll back the whole transaction; this resolution was added to version 3.23.43 */ diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 5b7d068d0c1..edaa555c555 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -730,8 +730,18 @@ sel_set_rec_lock( ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or LOC_REC_NOT_GAP */ que_thr_t* thr) /* in: query thread */ { + trx_t* trx; ulint err; + trx = thr_get_trx(thr); + + if (UT_LIST_GET_LEN(trx->trx_locks) > 10000) { + if (buf_LRU_buf_pool_running_out()) { + + return(DB_LOCK_TABLE_FULL); + } + } + if (index->type & DICT_CLUSTERED) { err = lock_clust_rec_read_check_and_lock(0, rec, index, mode, type, thr); @@ -2765,6 +2775,7 @@ row_search_for_mysql( /* out: DB_SUCCESS, DB_RECORD_NOT_FOUND, DB_END_OF_INDEX, DB_DEADLOCK, + DB_LOCK_TABLE_FULL, or DB_TOO_BIG_RECORD */ byte* buf, /* in/out: buffer for the fetched row in the MySQL format */ diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 9709f5235de..69341a1d7d1 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1172,6 +1172,9 @@ NetWare. */ } if (ret == NULL) { + fprintf(stderr, +"InnoDB: Fatal error: cannot allocate the memory for the buffer pool\n"); + return(DB_ERROR); } diff --git a/innobase/ut/ut0mem.c b/innobase/ut/ut0mem.c index a6002d7fd83..6ed61b0b5de 100644 --- a/innobase/ut/ut0mem.c +++ b/innobase/ut/ut0mem.c @@ -61,8 +61,10 @@ ut_malloc_low( /*==========*/ /* out, own: allocated memory */ ulint n, /* in: number of bytes to allocate */ - ibool set_to_zero) /* in: TRUE if allocated memory should be set + ibool set_to_zero, /* in: TRUE if allocated memory should be set to zero if UNIV_SET_MEM_TO_ZERO is defined */ + ibool assert_on_error) /* in: if TRUE, we crash mysqld if the memory + cannot be allocated */ { void* ret; @@ -86,9 +88,7 @@ ut_malloc_low( "InnoDB: Check if you should increase the swap file or\n" "InnoDB: ulimits of your operating system.\n" "InnoDB: On FreeBSD check you have compiled the OS with\n" - "InnoDB: a big enough maximum process size.\n" - "InnoDB: We now intentionally generate a seg fault so that\n" - "InnoDB: on Linux we get a stack trace.\n", + "InnoDB: a big enough maximum process size.\n", (ulong) n, (ulong) ut_total_allocated_memory, #ifdef __WIN__ (ulong) GetLastError() @@ -110,7 +110,15 @@ ut_malloc_low( /* Intentional segfault on NetWare causes an abend. Avoid this by graceful exit handling in ut_a(). */ #if (!defined __NETWARE__) - if (*ut_mem_null_ptr) ut_mem_null_ptr = 0; + if (assert_on_error) { + fprintf(stderr, + "InnoDB: We now intentionally generate a seg fault so that\n" + "InnoDB: on Linux we get a stack trace.\n"); + + if (*ut_mem_null_ptr) ut_mem_null_ptr = 0; + } else { + return(NULL); + } #else ut_a(0); #endif @@ -144,7 +152,7 @@ ut_malloc( /* out, own: allocated memory */ ulint n) /* in: number of bytes to allocate */ { - return(ut_malloc_low(n, TRUE)); + return(ut_malloc_low(n, TRUE, TRUE)); } /************************************************************************** From 5557ae747efdb8a1a8fe8841397231ee8265dfac Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 00:26:35 +0200 Subject: [PATCH 11/38] ha_innodb.cc: Add conversion of the InnoDB error DB_LOCK_TABLE_FULL to the corresponding MySQL error sql/ha_innodb.cc: Add conversion of the InnoDB error DB_LOCK_TABLE_FULL to the corresponding MySQL error --- sql/ha_innodb.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 07d8da63733..2515b4956d0 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -331,6 +331,9 @@ convert_error_code_to_mysql( } else if (error == (int) DB_NO_SAVEPOINT) { return(HA_ERR_NO_SAVEPOINT); + } else if (error == (int) DB_LOCK_TABLE_FULL) { + + return(HA_ERR_LOCK_TABLE_FULL); } else { return(-1); // Unknown error } From 60af920628c435a5990c3ef7a753d0f374fc12cc Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 02:31:22 +0200 Subject: [PATCH 12/38] Fixes while reviewing code (Cleanups and better bug fixes) mysql-test/r/select.result: Fixed test after wrong merge mysql-test/t/select.test: Fixed test after wrong merge scripts/mysql_fix_privilege_tables.sh: Don't read defaults files sql/item_cmpfunc.cc: Fix wrong value for not_null_tables_cache sql/item_cmpfunc.h: Remove wrong patch (flags are set in fix_length_and_dec()) sql/item_func.h: Fix wrong value for not_null_tables_cache sql/slave.cc: Fixed indentation --- mysql-test/r/select.result | 32 +++++++++++++-------------- mysql-test/t/select.test | 2 +- scripts/mysql_fix_privilege_tables.sh | 2 +- sql/item_cmpfunc.cc | 7 +++--- sql/item_cmpfunc.h | 3 --- sql/item_func.h | 2 +- sql/slave.cc | 3 ++- 7 files changed, 25 insertions(+), 26 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 3dd0603ed09..cc90547722f 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2327,22 +2327,6 @@ select * from t2,t3 where t2.s = t3.s; s s two two drop table t1, t2, t3; -CREATE TABLE t1 ( -i int(11) NOT NULL default '0', -c char(10) NOT NULL default '', -PRIMARY KEY (i), -UNIQUE KEY c (c) -) TYPE=MyISAM; -INSERT INTO t1 VALUES (1,'a'); -INSERT INTO t1 VALUES (2,'b'); -INSERT INTO t1 VALUES (3,'c'); -EXPLAIN SELECT i FROM t1 WHERE i=1; -table type possible_keys key key_len ref rows Extra -t1 const PRIMARY PRIMARY 4 const 1 Using index -EXPLAIN SELECT i FROM t1 WHERE i=1; -table type possible_keys key key_len ref rows Extra -t1 const PRIMARY PRIMARY 4 const 1 Using index -DROP TABLE t1; create table t1 (a integer, b integer, index(a), index(b)); create table t2 (c integer, d integer, index(c), index(d)); insert into t1 values (1,2), (2,2), (3,2), (4,2); @@ -2364,3 +2348,19 @@ a b c d 3 2 3 4 4 2 4 4 drop table t1, t2; +CREATE TABLE t1 ( +i int(11) NOT NULL default '0', +c char(10) NOT NULL default '', +PRIMARY KEY (i), +UNIQUE KEY c (c) +) TYPE=MyISAM; +INSERT INTO t1 VALUES (1,'a'); +INSERT INTO t1 VALUES (2,'b'); +INSERT INTO t1 VALUES (3,'c'); +EXPLAIN SELECT i FROM t1 WHERE i=1; +table type possible_keys key key_len ref rows Extra +t1 const PRIMARY PRIMARY 4 const 1 Using index +EXPLAIN SELECT i FROM t1 WHERE i=1; +table type possible_keys key key_len ref rows Extra +t1 const PRIMARY PRIMARY 4 const 1 Using index +DROP TABLE t1; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index f897703789b..e6b1ffbe8d7 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1887,7 +1887,7 @@ explain select * from t1 left join t2 on a=c where d in (4); select * from t1 left join t2 on a=c where d in (4); explain select * from t1 left join t2 on a=c where d = 4; select * from t1 left join t2 on a=c where d = 4; -drop table t1, t2;R +drop table t1, t2; # # Covering index is mentioned in EXPLAIN output for const tables (bug #5333) diff --git a/scripts/mysql_fix_privilege_tables.sh b/scripts/mysql_fix_privilege_tables.sh index 2fbcd76c318..381cf599e32 100644 --- a/scripts/mysql_fix_privilege_tables.sh +++ b/scripts/mysql_fix_privilege_tables.sh @@ -74,7 +74,7 @@ parse_arguments() parse_arguments "$@" if test -z "$cmd"; then - cmd="$bindir/mysql -f --user=$user --host=$host" + cmd="$bindir/mysql --no-defaults --force --user=$user --host=$host" if test ! -z "$root_password"; then cmd="$cmd --password=$root_password" fi diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index fbc1ad97e76..107a17815ae 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -293,9 +293,9 @@ void Item_func_interval::fix_length_and_dec() } maybe_null=0; max_length=2; used_tables_cache|= item->used_tables(); - not_null_tables_cache&= item->not_null_tables(); + not_null_tables_cache= item->not_null_tables(); with_sum_func= with_sum_func || item->with_sum_func; - const_item_cache&=item->const_item(); + const_item_cache&= item->const_item(); } @@ -1087,7 +1087,8 @@ void Item_func_in::fix_length_and_dec() maybe_null= item->maybe_null; max_length=2; used_tables_cache|= item->used_tables(); - not_null_tables_cache&= item->not_null_tables(); + /* not_null_tables_cache is only dependent on the argument to in */ + not_null_tables_cache= item->not_null_tables(); const_item_cache&= item->const_item(); } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index d36429ab61e..8f1aa525190 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -432,9 +432,6 @@ class Item_func_in :public Item_int_func { bool res= (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); with_sum_func= with_sum_func || item->with_sum_func; - used_tables_cache|= item->used_tables(); - not_null_tables_cache|= item->not_null_tables(); - const_item_cache&= item->const_item(); return res; } void fix_length_and_dec(); diff --git a/sql/item_func.h b/sql/item_func.h index 8a013f42c05..3627af4ebb1 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -600,7 +600,7 @@ public: { maybe_null=0; max_length=3; used_tables_cache|= item->used_tables(); - not_null_tables_cache&= item->not_null_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/slave.cc b/sql/slave.cc index 7e544572755..b0f911e7013 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1637,7 +1637,8 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, position is at the beginning of the file, and will read the "signature" and then fast-forward to the last position read. */ - if (thread_mask & SLAVE_SQL) { + if (thread_mask & SLAVE_SQL) + { my_b_seek(mi->rli.cur_log, (my_off_t) 0); } DBUG_RETURN(0); From 33d654d7e1dce86bf2dbbea6dda4979c4f2ff497 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 09:44:57 +0000 Subject: [PATCH 13/38] cleaned up code a bit added command CONNECT in management client added some verbose printouts removed prompt printout on !isatty(0) ndb/src/mgmapi/mgmapi.cpp: improved verbose printouts on connecting to management server ndb/src/mgmclient/CommandInterpreter.cpp: cleaned up code a bit added command CONNECT in management client added some verbose printouts ndb/src/mgmclient/main.cpp: removed prompt printout on !isatty(0) ndb/src/mgmclient/ndb_mgmclient.hpp: added verbose opotion --- ndb/src/mgmapi/mgmapi.cpp | 22 ++++-- ndb/src/mgmclient/CommandInterpreter.cpp | 97 +++++++++++++----------- ndb/src/mgmclient/main.cpp | 19 +++-- ndb/src/mgmclient/ndb_mgmclient.hpp | 2 +- 4 files changed, 81 insertions(+), 59 deletions(-) diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index ca3a2a2186d..831d14eac52 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -379,18 +379,30 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries, setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, "Unable to connect with connect string: %s", cfg.makeConnectString(buf,sizeof(buf))); + if (verbose == -2) + ndbout << ", failed." << endl; return -1; } if (verbose == -1) { - ndbout << "retrying every " << retry_delay_in_seconds << " seconds:"; + ndbout << "Retrying every " << retry_delay_in_seconds << " seconds"; + if (no_retries > 0) + ndbout << ". Attempts left:"; + else + ndbout << ", until connected.";; + ndbout << flush; verbose= -2; } - NdbSleep_SecSleep(retry_delay_in_seconds); - if (verbose == -2) { - ndbout << " " << no_retries; + if (no_retries > 0) { + if (verbose == -2) { + ndbout << " " << no_retries; + ndbout << flush; + } + no_retries--; } - no_retries--; + NdbSleep_SecSleep(retry_delay_in_seconds); } + if (verbose == -2) + ndbout << endl; handle->cfg_i = i; diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 54beaa49d3f..bfe8b6786b4 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -44,7 +44,7 @@ public: * Constructor * @param mgmtSrvr: Management server to use when executing commands */ - CommandInterpreter(const char *); + CommandInterpreter(const char *, int verbose); ~CommandInterpreter(); /** @@ -94,6 +94,7 @@ private: */ void executeHelp(char* parameters); void executeShow(char* parameters); + void executeConnect(char* parameters); void executePurge(char* parameters); void executeShutdown(char* parameters); void executeRun(char* parameters); @@ -153,6 +154,7 @@ private: NdbMgmHandle m_mgmsrv; bool connected; + int m_verbose; int try_reconnect; #ifdef HAVE_GLOBAL_REPLICATION NdbRepHandle m_repserver; @@ -169,9 +171,9 @@ private: #include "ndb_mgmclient.hpp" #include "ndb_mgmclient.h" -Ndb_mgmclient::Ndb_mgmclient(const char *host) +Ndb_mgmclient::Ndb_mgmclient(const char *host,int verbose) { - m_cmd= new CommandInterpreter(host); + m_cmd= new CommandInterpreter(host,verbose); } Ndb_mgmclient::~Ndb_mgmclient() { @@ -275,6 +277,7 @@ static const char* helpText = "REP CONNECT Connect to REP server on host:port\n" #endif "PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n" +"CONNECT Connect to management server (reconnect if already connected)\n" "QUIT Quit management client\n" ; @@ -373,7 +376,8 @@ convert(const char* s, int& val) { /* * Constructor */ -CommandInterpreter::CommandInterpreter(const char *_host) +CommandInterpreter::CommandInterpreter(const char *_host,int verbose) + : m_verbose(verbose) { m_mgmsrv = ndb_mgm_create_handle(); if(m_mgmsrv == NULL) { @@ -437,7 +441,15 @@ CommandInterpreter::connect() { if(!connected) { if(!ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1)) + { connected = true; + if (m_verbose) + { + printf("Connected to Management Server at: %s:%d\n", + ndb_mgm_get_connected_host(m_mgmsrv), + ndb_mgm_get_connected_port(m_mgmsrv)); + } + } } return connected; } @@ -445,7 +457,7 @@ CommandInterpreter::connect() bool CommandInterpreter::disconnect() { - if (ndb_mgm_disconnect(m_mgmsrv) == -1) { + if (connected && (ndb_mgm_disconnect(m_mgmsrv) == -1)) { ndbout_c("Could not disconnect from management server"); printError(); } @@ -459,18 +471,21 @@ CommandInterpreter::disconnect() int CommandInterpreter::execute(const char *_line, int _try_reconnect) { + DBUG_ENTER("CommandInterpreter::execute"); + DBUG_PRINT("info",("line=\"%s\"",_line)); + if (_try_reconnect >= 0) try_reconnect=_try_reconnect; char * line; if(_line == NULL) { // ndbout << endl; - return false; + DBUG_RETURN(false); } line = my_strdup(_line,MYF(MY_WME)); My_auto_ptr ptr(line); if (emptyString(line)) { - return true; + DBUG_RETURN(true); } for (unsigned int i = 0; i < strlen(line); ++i) { @@ -484,41 +499,49 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect) if (strcmp(firstToken, "HELP") == 0 || strcmp(firstToken, "?") == 0) { executeHelp(allAfterFirstToken); - return true; + DBUG_RETURN(true); } - else if (strcmp(firstToken, "SHOW") == 0) { + else if (strcmp(firstToken, "CONNECT") == 0) { + executeConnect(allAfterFirstToken); + DBUG_RETURN(true); + } + + if (!connect()) + DBUG_RETURN(true); + + if (strcmp(firstToken, "SHOW") == 0) { executeShow(allAfterFirstToken); - return true; + DBUG_RETURN(true); } else if (strcmp(firstToken, "SHUTDOWN") == 0) { executeShutdown(allAfterFirstToken); - return true; + DBUG_RETURN(true); } else if (strcmp(firstToken, "CLUSTERLOG") == 0){ executeClusterLog(allAfterFirstToken); - return true; + DBUG_RETURN(true); } else if(strcmp(firstToken, "START") == 0 && allAfterFirstToken != NULL && strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ executeStartBackup(allAfterFirstToken); - return true; + DBUG_RETURN(true); } else if(strcmp(firstToken, "ABORT") == 0 && allAfterFirstToken != NULL && strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ executeAbortBackup(allAfterFirstToken); - return true; + DBUG_RETURN(true); } else if (strcmp(firstToken, "PURGE") == 0) { executePurge(allAfterFirstToken); - return true; + DBUG_RETURN(true); } #ifdef HAVE_GLOBAL_REPLICATION else if(strcmp(firstToken, "REPLICATION") == 0 || strcmp(firstToken, "REP") == 0) { executeRep(allAfterFirstToken); - return true; + DBUG_RETURN(true); } #endif // HAVE_GLOBAL_REPLICATION else if(strcmp(firstToken, "ENTER") == 0 && @@ -526,14 +549,14 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect) strncmp(allAfterFirstToken, "SINGLE USER MODE ", sizeof("SINGLE USER MODE") - 1) == 0){ executeEnterSingleUser(allAfterFirstToken); - return true; + DBUG_RETURN(true); } else if(strcmp(firstToken, "EXIT") == 0 && allAfterFirstToken != NULL && strncmp(allAfterFirstToken, "SINGLE USER MODE ", sizeof("SINGLE USER MODE") - 1) == 0){ executeExitSingleUser(allAfterFirstToken); - return true; + DBUG_RETURN(true); } else if (strcmp(firstToken, "ALL") == 0) { analyseAfterFirstToken(-1, allAfterFirstToken); @@ -542,7 +565,7 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect) strcmp(firstToken, "EXIT") == 0 || strcmp(firstToken, "BYE") == 0) && allAfterFirstToken == NULL){ - return false; + DBUG_RETURN(false); } else { /** * First token should be a digit, node ID @@ -552,18 +575,18 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect) if (! convert(firstToken, nodeId)) { ndbout << "Invalid command: " << line << endl; ndbout << "Type HELP for help." << endl << endl; - return true; + DBUG_RETURN(true); } if (nodeId < 0) { ndbout << "Invalid node ID: " << firstToken << "." << endl; - return true; + DBUG_RETURN(true); } analyseAfterFirstToken(nodeId, allAfterFirstToken); } - return true; + DBUG_RETURN(true); } @@ -692,7 +715,6 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun, ndbout_c("Trying to start all nodes of system."); ndbout_c("Use ALL STATUS to see the system start-up phases."); } else { - connect(); struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(m_mgmsrv); if(cl == 0){ ndbout_c("Unable get status from management server"); @@ -826,8 +848,6 @@ CommandInterpreter::executeHelp(char* parameters) void CommandInterpreter::executeShutdown(char* parameters) { - connect(); - ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv); if(state == NULL) { ndbout_c("Could not get status"); @@ -979,7 +999,6 @@ CommandInterpreter::executePurge(char* parameters) int i; char *str; - connect(); if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) { ndbout_c("Command failed"); @@ -999,7 +1018,6 @@ void CommandInterpreter::executeShow(char* parameters) { int i; - connect(); if (emptyString(parameters)) { ndbout << "Cluster Configuration" << endl << "---------------------" << endl; @@ -1087,6 +1105,12 @@ CommandInterpreter::executeShow(char* parameters) } } +void +CommandInterpreter::executeConnect(char* parameters) +{ + disconnect(); + connect(); +} //***************************************************************************** //***************************************************************************** @@ -1094,7 +1118,6 @@ void CommandInterpreter::executeClusterLog(char* parameters) { int i; - connect(); if (parameters != 0 && strlen(parameters) != 0) { enum ndb_mgm_clusterlog_level severity = NDB_MGM_CLUSTERLOG_ALL; int isOk = true; @@ -1240,7 +1263,6 @@ CommandInterpreter::executeClusterLog(char* parameters) void CommandInterpreter::executeStop(int processId, const char *, bool all) { - connect(); int result = 0; if(all) { result = ndb_mgm_stop(m_mgmsrv, 0, 0); @@ -1262,7 +1284,6 @@ CommandInterpreter::executeStop(int processId, const char *, bool all) void CommandInterpreter::executeEnterSingleUser(char* parameters) { - connect(); strtok(parameters, " "); struct ndb_mgm_reply reply; char* id = strtok(NULL, " "); @@ -1289,7 +1310,6 @@ CommandInterpreter::executeEnterSingleUser(char* parameters) void CommandInterpreter::executeExitSingleUser(char* parameters) { - connect(); int result = ndb_mgm_exit_single_user(m_mgmsrv, 0); if (result != 0) { ndbout_c("Exiting single user mode failed."); @@ -1304,7 +1324,6 @@ void CommandInterpreter::executeStart(int processId, const char* parameters, bool all) { - connect(); int result; if(all) { result = ndb_mgm_start(m_mgmsrv, 0, 0); @@ -1328,7 +1347,6 @@ void CommandInterpreter::executeRestart(int processId, const char* parameters, bool all) { - connect(); int result; int nostart = 0; int initialstart = 0; @@ -1378,7 +1396,6 @@ CommandInterpreter::executeDumpState(int processId, const char* parameters, ndbout << "Expected argument" << endl; return; } - connect(); Uint32 no = 0; int pars[25]; @@ -1418,7 +1435,6 @@ CommandInterpreter::executeStatus(int processId, return; } - connect(); ndb_mgm_node_status status; Uint32 startPhase, version; bool system; @@ -1469,7 +1485,6 @@ void CommandInterpreter::executeLogLevel(int processId, const char* parameters, bool all) { - connect(); (void) all; BaseString tmp(parameters); @@ -1525,7 +1540,6 @@ void CommandInterpreter::executeError(int processId, return; } - connect(); // Copy parameters since strtok will modify it char* newpar = my_strdup(parameters,MYF(MY_WME)); My_auto_ptr ap1(newpar); @@ -1589,7 +1603,6 @@ void CommandInterpreter::executeLog(int processId, const char* parameters, bool all) { - connect(); struct ndb_mgm_reply reply; Vector blocks; if (! parseBlockSpecification(parameters, blocks)) { @@ -1657,7 +1670,6 @@ CommandInterpreter::executeTestOn(int processId, ndbout << "No parameters expected to this command." << endl; return; } - connect(); struct ndb_mgm_reply reply; int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &reply); if (result != 0) { @@ -1676,7 +1688,6 @@ CommandInterpreter::executeTestOff(int processId, ndbout << "No parameters expected to this command." << endl; return; } - connect(); struct ndb_mgm_reply reply; int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &reply); if (result != 0) { @@ -1798,8 +1809,6 @@ CommandInterpreter::executeEventReporting(int processId, ndbout << "Expected argument" << endl; return; } - connect(); - BaseString tmp(parameters); Vector spec; tmp.split(spec, "="); @@ -1850,7 +1859,6 @@ CommandInterpreter::executeEventReporting(int processId, void CommandInterpreter::executeStartBackup(char* /*parameters*/) { - connect(); struct ndb_mgm_reply reply; unsigned int backupId; @@ -1897,8 +1905,6 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/) void CommandInterpreter::executeAbortBackup(char* parameters) { - connect(); - strtok(parameters, " "); struct ndb_mgm_reply reply; char* id = strtok(NULL, "\0"); @@ -1952,7 +1958,6 @@ CommandInterpreter::executeRep(char* parameters) return; } - connect(); char * line = my_strdup(parameters,MYF(MY_WME)); My_auto_ptr ap1((char*)line); char * firstToken = strtok(line, " "); diff --git a/ndb/src/mgmclient/main.cpp b/ndb/src/mgmclient/main.cpp index f32cc683296..08d5d60cfab 100644 --- a/ndb/src/mgmclient/main.cpp +++ b/ndb/src/mgmclient/main.cpp @@ -56,17 +56,18 @@ handler(int sig){ } } - +static const char default_prompt[]= "ndb_mgm> "; static unsigned _try_reconnect; static char *opt_connect_str= 0; +static const char *prompt= default_prompt; static struct my_option my_long_options[] = { NDB_STD_OPTS("ndb_mgm"), { "try-reconnect", 't', - "Specify number of retries for connecting to ndb_mgmd, default infinite", + "Specify number of tries for connecting to ndb_mgmd (0 = infinite)", (gptr*) &_try_reconnect, (gptr*) &_try_reconnect, 0, - GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + GET_UINT, REQUIRED_ARG, 3, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; static void short_usage_sub(void) @@ -116,13 +117,13 @@ read_and_execute(int _try_reconnect) } #ifdef HAVE_READLINE /* Get a line from the user. */ - line_read = readline ("ndb_mgm> "); + line_read = readline (prompt); /* If the line has any text in it, save it on the history. */ if (line_read && *line_read) add_history (line_read); #else static char linebuffer[254]; - fputs("ndb_mgm> ", stdout); + fputs(prompt, stdout); linebuffer[sizeof(linebuffer)-1]=0; line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin); if (line_read == linebuffer) { @@ -155,12 +156,16 @@ int main(int argc, char** argv){ opt_connect_str= buf; } + if (!isatty(0)) + { + prompt= 0; + } + ndbout << "-- NDB Cluster -- Management Client --" << endl; - printf("Connecting to Management Server: %s\n", opt_connect_str ? opt_connect_str : "default"); signal(SIGPIPE, handler); - com = new Ndb_mgmclient(opt_connect_str); + com = new Ndb_mgmclient(opt_connect_str,1); while(read_and_execute(_try_reconnect)); delete com; diff --git a/ndb/src/mgmclient/ndb_mgmclient.hpp b/ndb/src/mgmclient/ndb_mgmclient.hpp index f6bcebc3896..ea592dfdf4e 100644 --- a/ndb/src/mgmclient/ndb_mgmclient.hpp +++ b/ndb/src/mgmclient/ndb_mgmclient.hpp @@ -21,7 +21,7 @@ class CommandInterpreter; class Ndb_mgmclient { public: - Ndb_mgmclient(const char*); + Ndb_mgmclient(const char*,int verbose=0); ~Ndb_mgmclient(); int execute(const char *_line, int _try_reconnect=-1); int execute(int argc, char** argv, int _try_reconnect=-1); From 31e9caa05c9da4d8e7d43428aca747c7cf965502 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 14:02:39 +0400 Subject: [PATCH 14/38] Portability fix: we had problems with -1.1E-38, -2.2E-308 values on 64-bit platforms (due to compiler's optimization). -1.1E-38 replaced with -1.1E-37 -2.2E-308 replaced with -2.2E-307 --- mysql-test/r/strict.result | 16 ++++++++-------- mysql-test/t/strict.test | 8 ++++---- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 19c4def9b32..b7c5ac38b76 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -713,8 +713,8 @@ NULL -99.99 DROP TABLE t1; CREATE TABLE t1 (col1 FLOAT, col2 FLOAT UNSIGNED); -INSERT INTO t1 VALUES (-1.1E-38,0),(+3.4E+38,+3.4E+38); -INSERT INTO t1 VALUES ('-1.1E-38',0),('+3.4E+38','+3.4E+38'); +INSERT INTO t1 VALUES (-1.1E-37,0),(+3.4E+38,+3.4E+38); +INSERT INTO t1 VALUES ('-1.1E-37',0),('+3.4E+38','+3.4E+38'); INSERT INTO t1 (col1) VALUES (3E-46); INSERT INTO t1 (col1) VALUES (+3.4E+39); ERROR 22003: Out of range value adjusted for column 'col1' at row 1 @@ -752,9 +752,9 @@ Warning 1264 Out of range value adjusted for column 'col1' at row 1 Warning 1264 Out of range value adjusted for column 'col2' at row 1 SELECT * FROM t1; col1 col2 --1.1e-38 0 +-1.1e-37 0 3.4e+38 3.4e+38 --1.1e-38 0 +-1.1e-37 0 3.4e+38 3.4e+38 0 NULL 2 NULL @@ -763,8 +763,8 @@ NULL NULL 3.40282e+38 0 DROP TABLE t1; CREATE TABLE t1 (col1 DOUBLE PRECISION, col2 DOUBLE PRECISION UNSIGNED); -INSERT INTO t1 VALUES (-2.2E-308,0),(+1.7E+308,+1.7E+308); -INSERT INTO t1 VALUES ('-2.2E-308',0),('+1.7E+308','+1.7E+308'); +INSERT INTO t1 VALUES (-2.2E-307,0),(+1.7E+308,+1.7E+308); +INSERT INTO t1 VALUES ('-2.2E-307',0),('+1.7E+308','+1.7E+308'); INSERT INTO t1 (col1) VALUES (-2.2E-330); INSERT INTO t1 (col1) VALUES (+1.7E+309); ERROR 22007: Illegal double '1.7E+309' value found during parsing @@ -801,9 +801,9 @@ Warning 1264 Out of range value adjusted for column 'col2' at row 1 Warning 1264 Out of range value adjusted for column 'col2' at row 1 SELECT * FROM t1; col1 col2 --2.2e-308 0 +-2.2e-307 0 1.7e+308 1.7e+308 --2.2e-308 0 +-2.2e-307 0 1.7e+308 1.7e+308 0 NULL 2 NULL diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index d9f4f4f2d0c..4f7c0cfc541 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -493,8 +493,8 @@ DROP TABLE t1; # Test INSERT with FLOAT CREATE TABLE t1 (col1 FLOAT, col2 FLOAT UNSIGNED); -INSERT INTO t1 VALUES (-1.1E-38,0),(+3.4E+38,+3.4E+38); -INSERT INTO t1 VALUES ('-1.1E-38',0),('+3.4E+38','+3.4E+38'); +INSERT INTO t1 VALUES (-1.1E-37,0),(+3.4E+38,+3.4E+38); +INSERT INTO t1 VALUES ('-1.1E-37',0),('+3.4E+38','+3.4E+38'); # We don't give warnings for underflow INSERT INTO t1 (col1) VALUES (3E-46); --error 1264 @@ -527,8 +527,8 @@ DROP TABLE t1; # Test INSERT with DOUBLE CREATE TABLE t1 (col1 DOUBLE PRECISION, col2 DOUBLE PRECISION UNSIGNED); -INSERT INTO t1 VALUES (-2.2E-308,0),(+1.7E+308,+1.7E+308); -INSERT INTO t1 VALUES ('-2.2E-308',0),('+1.7E+308','+1.7E+308'); +INSERT INTO t1 VALUES (-2.2E-307,0),(+1.7E+308,+1.7E+308); +INSERT INTO t1 VALUES ('-2.2E-307',0),('+1.7E+308','+1.7E+308'); # We don't give warnings for underflow INSERT INTO t1 (col1) VALUES (-2.2E-330); --error 1367 From 2c2333e5f2f5bda27dd1079ba9302aa1fb200f2b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 11:18:20 +0100 Subject: [PATCH 15/38] Changed test to remove node name from output. (was from WL#2050 - CREATE USER and DROP USER and RENAME USER) mysql-test/r/grant2.result: Replaced test results after removing node name from output. (was from WL#2050 - CREATE USER and DROP USER and RENAME USER) --- mysql-test/r/grant2.result | 13 ++++++------- mysql-test/t/grant2.test | 10 ++++++---- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index fee9150ca50..f2782f6f605 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -136,6 +136,10 @@ GRANT INSERT ON "test".* TO 'mysqltest_1'@'%' GRANT UPDATE (c2) ON "test"."t2" TO 'mysqltest_1'@'%' GRANT UPDATE ON "test"."t1" TO 'mysqltest_1'@'%' drop user 'mysqltest_1', 'mysqltest_3'; +grant all on test.t1 to 'mysqltest_1'; +ERROR 42000: 'root'@'localhost' is not allowed to create new users +drop user 'mysqltest_1'; +ERROR HY000: Operation DROP USER failed for 1 of the requested users drop table t1, t2; insert into mysql.db set user='mysqltest_1', db='%', host='%'; flush privileges; @@ -197,7 +201,7 @@ GRANT SELECT ON "mysql".* TO '%@a'@'a' drop user '%@a'@'a'; create user mysqltest_2@localhost; grant usage on *.* to mysqltest_2@localhost with grant option; -select host,user,password from mysql.user order by host,user,password; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; ERROR 42000: Access denied for user 'mysqltest_2'@'localhost' to database 'mysql' create user mysqltest_A@'%'; rename user mysqltest_A@'%' to mysqltest_B@'%'; @@ -205,15 +209,10 @@ drop user mysqltest_B@'%'; drop user mysqltest_2@localhost; create user mysqltest_3@localhost; grant all privileges on mysql.* to mysqltest_3@localhost; -select host,user,password from mysql.user order by host,user,password; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; host user password % mysqltest_2 *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 -127.0.0.1 root -chilla% -chilla% root -localhost localhost mysqltest_3 -localhost root insert into mysql.user set host='%', user='mysqltest_B'; create user mysqltest_A@'%'; ERROR 42000: Access denied for user 'mysqltest_3'@'localhost' to database 'mysql' diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index c439bd05d2f..70cec9e0e35 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -125,8 +125,10 @@ show grants for 'mysqltest_1'; drop user 'mysqltest_1', 'mysqltest_3'; # # Grant must not create user -#grant all on test.t1 to 'mysqltest_1'; -#drop user 'mysqltest_1'; +--error 1211 +grant all on test.t1 to 'mysqltest_1'; +--error 1268 +drop user 'mysqltest_1'; # # Cleanup drop table t1, t2; @@ -198,7 +200,7 @@ grant usage on *.* to mysqltest_2@localhost with grant option; connect (user2,localhost,mysqltest_2,,); connection user2; --error 1044 -select host,user,password from mysql.user order by host,user,password; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; create user mysqltest_A@'%'; rename user mysqltest_A@'%' to mysqltest_B@'%'; drop user mysqltest_B@'%'; @@ -211,7 +213,7 @@ create user mysqltest_3@localhost; grant all privileges on mysql.* to mysqltest_3@localhost; connect (user3,localhost,mysqltest_3,,); connection user3; -select host,user,password from mysql.user order by host,user,password; +select host,user,password from mysql.user where user like 'mysqltest_%' order by host,user,password; insert into mysql.user set host='%', user='mysqltest_B'; --error 1044 create user mysqltest_A@'%'; From 88ac05648df484d0de5163ac46c6b3c3082f5447 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 12:28:12 +0200 Subject: [PATCH 16/38] fixed redifinition of variable --- sql/sql_view.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 81d8000831b..ec63bb92c54 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -684,7 +684,7 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) mark to avoid temporary table using and put view reference and find last view table */ - for (TABLE_LIST *tbl= view_tables; + for (tbl= view_tables; tbl; tbl= (view_tables_tail= tbl)->next_global) { From 59abcd447cc373c1c3dfc0184f12642aa6d2ab70 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 13:16:37 +0200 Subject: [PATCH 17/38] srv0srv.c: srv_lock_timeout_and_monitor_thread(): write to srv_monitor_file only if --innodb_status_file=1 innobase/srv/srv0srv.c: srv_lock_timeout_and_monitor_thread(): write to srv_monitor_file only if --innodb_status_file=1 --- innobase/srv/srv0srv.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index 0a814268a36..99a2db57d79 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -1617,11 +1617,13 @@ loop: srv_printf_innodb_monitor(stderr); } - mutex_enter(&srv_monitor_file_mutex); - rewind(srv_monitor_file); - srv_printf_innodb_monitor(srv_monitor_file); - os_file_set_eof(srv_monitor_file); - mutex_exit(&srv_monitor_file_mutex); + if (srv_innodb_status) { + mutex_enter(&srv_monitor_file_mutex); + rewind(srv_monitor_file); + srv_printf_innodb_monitor(srv_monitor_file); + os_file_set_eof(srv_monitor_file); + mutex_exit(&srv_monitor_file_mutex); + } if (srv_print_innodb_tablespace_monitor && difftime(current_time, last_table_monitor_time) > 60) { From b0d586e5648e78981c63e68059c6c836a228a082 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 13:20:48 +0000 Subject: [PATCH 18/38] added error code message for 897 --- ndb/src/ndbapi/ndberror.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index bc49358cc63..6744f4c1640 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -241,11 +241,12 @@ ErrorBundle ErrorCodes[] = { { 877, AE, "877" }, { 878, AE, "878" }, { 879, AE, "879" }, + { 880, AE, "Tried to read too much - too many getValue calls" }, { 884, AE, "Stack overflow in interpreter" }, { 885, AE, "Stack underflow in interpreter" }, { 886, AE, "More than 65535 instructions executed in interpreter" }, + { 897, AE, "Update attempt of primary key via ndbcluster internal api (if this occurs via the MySQL server it is a bug, please report)" }, { 4256, AE, "Must call Ndb::init() before this function" }, - { 880, AE, "Tried to read too much - too many getValue calls" }, { 4257, AE, "Tried to read too much - too many getValue calls" }, /** From 12163e08932c2b828b0f5d98990c2a84eb3f0710 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 16:30:20 +0200 Subject: [PATCH 19/38] portability fix (some printf lack of NULL support in strings) --- sql/item.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index f8dc0c6eec8..d1ebdb1822f 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -187,9 +187,12 @@ void Item_ident::cleanup() { DBUG_ENTER("Item_ident::cleanup"); DBUG_PRINT("enter", ("b:%s(%s), t:%s(%s), f:%s(%s)", - db_name, orig_db_name, - table_name, orig_table_name, - field_name, orig_field_name)); + db_name ? db_name : "(null)", + orig_db_name ? orig_db_name : "(null)", + table_name ? table_name : "(null)", + orig_table_name ? orig_table_name : "(null)", + field_name ? field_name : "(null)", + orig_field_name ? orig_field_name : "(null)")); Item::cleanup(); db_name= orig_db_name; table_name= orig_table_name; From 04d6d45f6e9f83d2d5fbbc495d81f8393d41d872 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 18:26:52 +0300 Subject: [PATCH 20/38] portability fix(for powermac) Fix for bug#6756: Crash if SHOW INDEX mysql-test/r/information_schema.result: portability fix(for powermac) mysql-test/t/information_schema.test: portability fix(for powermac) --- mysql-test/r/information_schema.result | 46 +++++++++++++++++--------- mysql-test/t/information_schema.test | 29 +++++++++++----- sql/sql_show.cc | 11 +++--- 3 files changed, 59 insertions(+), 27 deletions(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 8f5ac88b7d0..cba78422253 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -252,7 +252,7 @@ sel2 sel2 select count(*) from information_schema.ROUTINES; count(*) 2 -create view v0 (c) as select schema_name from information_schema.SCHEMATA; +create view v0 (c) as select schema_name from information_schema.schemata; select * from v0; c mysql @@ -260,22 +260,22 @@ test explain select * from v0; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY # ALL NULL NULL NULL NULL 2 -create view v1 (c) as select table_name from information_schema.TABLES +create view v1 (c) as select table_name from information_schema.tables where table_name="v1"; select * from v1; c v1 -create view v2 (c) as select column_name from information_schema.COLUMNS +create view v2 (c) as select column_name from information_schema.columns where table_name="v2"; select * from v2; c c -create view v3 (c) as select CHARACTER_SET_NAME from information_schema.CHARACTER_SETS +create view v3 (c) as select CHARACTER_SET_NAME from information_schema.character_sets where CHARACTER_SET_NAME like "latin1%"; select * from v3; c latin1 -create view v4 (c) as select COLLATION_NAME from information_schema.COLLATIONS +create view v4 (c) as select COLLATION_NAME from information_schema.collations where COLLATION_NAME like "latin1%"; select * from v4; c @@ -289,13 +289,13 @@ latin1_general_cs latin1_spanish_ci show keys from v4; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment -select * from information_schema.VIEWS where TABLE_NAME like "v%"; +select * from information_schema.views where TABLE_NAME like "v%"; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME VIEW_DEFINITION CHECK_OPTION IS_UPDATABLE -NULL test v0 select `SCHEMATA`.`SCHEMA_NAME` AS `c` from `information_schema`.`SCHEMATA` NONE NO -NULL test v1 select `TABLES`.`TABLE_NAME` AS `c` from `information_schema`.`TABLES` where (`TABLES`.`TABLE_NAME` = _utf8'v1') NONE NO -NULL test v2 select `COLUMNS`.`COLUMN_NAME` AS `c` from `information_schema`.`COLUMNS` where (`COLUMNS`.`TABLE_NAME` = _utf8'v2') NONE NO -NULL test v3 select `CHARACTER_SETS`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`CHARACTER_SETS` where (`CHARACTER_SETS`.`CHARACTER_SET_NAME` like _utf8'latin1%') NONE NO -NULL test v4 select `COLLATIONS`.`COLLATION_NAME` AS `c` from `information_schema`.`COLLATIONS` where (`COLLATIONS`.`COLLATION_NAME` like _utf8'latin1%') NONE NO +NULL test v0 select `schemata`.`SCHEMA_NAME` AS `c` from `information_schema`.`schemata` NONE NO +NULL test v1 select `tables`.`TABLE_NAME` AS `c` from `information_schema`.`tables` where (`tables`.`TABLE_NAME` = _utf8'v1') NONE NO +NULL test v2 select `columns`.`COLUMN_NAME` AS `c` from `information_schema`.`columns` where (`columns`.`TABLE_NAME` = _utf8'v2') NONE NO +NULL test v3 select `character_sets`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`character_sets` where (`character_sets`.`CHARACTER_SET_NAME` like _utf8'latin1%') NONE NO +NULL test v4 select `collations`.`COLLATION_NAME` AS `c` from `information_schema`.`collations` where (`collations`.`COLLATION_NAME` like _utf8'latin1%') NONE NO drop view v0, v1, v2, v3, v4; create table t1 (a int); grant select,update,insert on t1 to mysqltest_1@localhost; @@ -434,18 +434,18 @@ information_schema.tables; s1 9 drop table t1; -SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS; +SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets; Table Create Table -CHARACTER_SETS CREATE TEMPORARY TABLE `CHARACTER_SETS` ( +character_sets CREATE TEMPORARY TABLE `character_sets` ( `CHARACTER_SET_NAME` char(30) NOT NULL default '', `DESCRIPTION` char(60) NOT NULL default '', `DEFAULT_COLLATE_NAME` char(60) NOT NULL default '', `MAXLEN` bigint(3) NOT NULL default '0' ) ENGINE=HEAP DEFAULT CHARSET=utf8 MAX_ROWS=2282 set names latin2; -SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS; +SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets; Table Create Table -CHARACTER_SETS CREATE TEMPORARY TABLE `CHARACTER_SETS` ( +character_sets CREATE TEMPORARY TABLE `character_sets` ( `CHARACTER_SET_NAME` char(30) NOT NULL default '', `DESCRIPTION` char(60) NOT NULL default '', `DEFAULT_COLLATE_NAME` char(60) NOT NULL default '', @@ -517,3 +517,19 @@ from information_schema.columns; open c; open c; end;// call p108()// ERROR 24000: Cursor is already open drop procedure p108; +create view v1 as select A1.table_name from information_schema.TABLES A1 +where table_name= "user"; +select * from v1; +table_name +user +drop view v1; +create view vo as select 'a' union select 'a'; +show index from vo; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +select * from information_schema.TABLE_CONSTRAINTS where +TABLE_NAME= "vo"; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE CONSTRAINT_METHOD +select * from information_schema.KEY_COLUMN_USAGE where +TABLE_NAME= "vo"; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +drop view vo; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 411301445a3..93e201c5121 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -110,24 +110,24 @@ select count(*) from information_schema.ROUTINES; # # Test for views # -create view v0 (c) as select schema_name from information_schema.SCHEMATA; +create view v0 (c) as select schema_name from information_schema.schemata; select * from v0; --replace_column 3 # explain select * from v0; -create view v1 (c) as select table_name from information_schema.TABLES +create view v1 (c) as select table_name from information_schema.tables where table_name="v1"; select * from v1; -create view v2 (c) as select column_name from information_schema.COLUMNS +create view v2 (c) as select column_name from information_schema.columns where table_name="v2"; select * from v2; -create view v3 (c) as select CHARACTER_SET_NAME from information_schema.CHARACTER_SETS +create view v3 (c) as select CHARACTER_SET_NAME from information_schema.character_sets where CHARACTER_SET_NAME like "latin1%"; select * from v3; -create view v4 (c) as select COLLATION_NAME from information_schema.COLLATIONS +create view v4 (c) as select COLLATION_NAME from information_schema.collations where COLLATION_NAME like "latin1%"; select * from v4; show keys from v4; -select * from information_schema.VIEWS where TABLE_NAME like "v%"; +select * from information_schema.views where TABLE_NAME like "v%"; drop view v0, v1, v2, v3, v4; # @@ -222,9 +222,9 @@ information_schema.tables) union select version from information_schema.tables; drop table t1; -SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS; +SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets; set names latin2; -SHOW CREATE TABLE INFORMATION_SCHEMA.CHARACTER_SETS; +SHOW CREATE TABLE INFORMATION_SCHEMA.character_sets; set names latin1; create table t1 select * from information_schema.CHARACTER_SETS @@ -260,3 +260,16 @@ from information_schema.columns; open c; open c; end;// call p108()// delimiter ;// drop procedure p108; + +create view v1 as select A1.table_name from information_schema.TABLES A1 +where table_name= "user"; +select * from v1; +drop view v1; + +create view vo as select 'a' union select 'a'; +show index from vo; +select * from information_schema.TABLE_CONSTRAINTS where +TABLE_NAME= "vo"; +select * from information_schema.KEY_COLUMN_USAGE where +TABLE_NAME= "vo"; +drop view vo; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 55c38ff37c9..19b5562cb8b 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2628,7 +2628,7 @@ static int get_schema_stat_record(THD *thd, struct st_table_list *tables, { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_stat_record"); - if (!res) + if (!res && !tables->view) { TABLE *show_table= tables->table; KEY *key_info=show_table->key_info; @@ -2737,7 +2737,7 @@ static int get_schema_constarints_record(THD *thd, struct st_table_list *tables, { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_constarints_record"); - if (!res) + if (!res && !tables->view) { List f_key_list; TABLE *show_table= tables->table; @@ -2792,7 +2792,7 @@ static int get_schema_key_column_usage_record(THD *thd, { DBUG_ENTER("get_schema_key_column_usage_record"); CHARSET_INFO *cs= system_charset_info; - if (!res) + if (!res && !tables->view) { List f_key_list; TABLE *show_table= tables->table; @@ -2960,7 +2960,7 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) field_list, (ORDER*) 0, 0, 0, (select_lex->options | thd->options | TMP_TABLE_ALL_COLUMNS), - HA_POS_ERROR, table_list->real_name))) + HA_POS_ERROR, table_list->alias))) DBUG_RETURN(0); DBUG_RETURN(table); } @@ -3136,6 +3136,9 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list) } table->tmp_table= TMP_TABLE; table->grant.privilege= SELECT_ACL; + table->alias_name_used= my_strcasecmp(table_alias_charset, + table_list->real_name, + table_list->alias); table_list->schema_table_name= table_list->real_name; table_list->real_name= table->real_name; table_list->table= table; From 7f9125b205243040546853553710f02ed609d710 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 15:27:45 +0000 Subject: [PATCH 21/38] fixed ndb_grant test --- mysql-test/r/ndb_grant.result | 38 ++++++++++++++++++++++++++++++----- mysql-test/t/ndb_grant.test | 13 ++++++++++-- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/ndb_grant.result b/mysql-test/r/ndb_grant.result index 6583065a0c4..6192a7cace5 100644 --- a/mysql-test/r/ndb_grant.result +++ b/mysql-test/r/ndb_grant.result @@ -31,8 +31,8 @@ begin; grant delete on mysqltest.* to mysqltest_1@localhost; commit; select * from mysql.user where user="mysqltest_1"; -Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections -localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv Create_view_priv Show_view_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N 0 0 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' @@ -99,7 +99,7 @@ commit; show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' -GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, REFERENCES, INDEX, CREATE TEMPORARY TABLES, CREATE VIEW, SHOW VIEW ON `mysqltest`.* TO 'mysqltest_1'@'localhost' WITH GRANT OPTION begin; revoke all privileges on mysqltest.* from mysqltest_1@localhost; commit; @@ -271,23 +271,26 @@ grant select on test.t1 to drop_user2@localhost; grant select on test.* to drop_user3@localhost; grant select on *.* to drop_user4@localhost; commit; +flush privileges; 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 begin; revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; +ERROR HY000: Can't revoke all privileges, grant for one or more of the requested users commit; +flush privileges; drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; drop table t1; begin; grant usage on *.* to mysqltest_1@localhost identified by "password"; -grant select, update, insert on test.* to mysqltest@localhost; +grant select, update, insert on test.* to mysqltest_1@localhost; commit; show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' IDENTIFIED BY PASSWORD '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19' +GRANT SELECT, INSERT, UPDATE ON `test`.* TO 'mysqltest_1'@'localhost' drop user mysqltest_1@localhost; SET NAMES koi8r; CREATE DATABASE ÂÄ; @@ -396,6 +399,31 @@ DROP DATABASE testdb7; DROP DATABASE testdb8; DROP DATABASE testdb9; DROP DATABASE testdb10; +SHOW PRIVILEGES; +Privilege Context Comment +Alter Tables To alter the table +Create Databases,Tables,Indexes To create new databases and tables +Create temporary tables Databases To use CREATE TEMPORARY TABLE +Create view Tables To create new views +Delete Tables To delete existing rows +Drop Databases,Tables To drop databases, tables, and views +File File access on server To read and write files on the server +Grant option Databases,Tables To give to other users those privileges you possess +Index Tables To create or drop indexes +Insert Tables To insert data into tables +Lock tables Databases To use LOCK TABLES (together with SELECT privilege) +Process Server Admin To view the plain text of currently executing queries +References Databases,Tables To have references on tables +Reload Server Admin To reload or refresh tables, logs and privileges +Replication client Server Admin To ask where the slave or master servers are +Replication slave Server Admin To read binary log events from the master +Select Tables To retrieve rows from table +Show databases Server Admin To see all databases with SHOW DATABASES +Show view Tables To see views with SHOW CREATE VIEW +Shutdown Server Admin To shut down the server +Super Server Admin To use KILL thread, SET GLOBAL, CHANGE MASTER, etc. +Update Tables To update existing rows +Usage Server Admin No privileges - allow connect only use mysql; alter table columns_priv engine=myisam; alter table db engine=myisam; diff --git a/mysql-test/t/ndb_grant.test b/mysql-test/t/ndb_grant.test index d3899d9972f..b4885d2c5fc 100644 --- a/mysql-test/t/ndb_grant.test +++ b/mysql-test/t/ndb_grant.test @@ -226,19 +226,23 @@ grant select on test.t1 to drop_user2@localhost; grant select on test.* to drop_user3@localhost; grant select on *.* to drop_user4@localhost; commit; ---error 1268 +flush privileges; +# Drop user now implicitly revokes all privileges. drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; begin; +--error 1269 revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; commit; +flush privileges; +#--error 1268 drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; drop table t1; begin; grant usage on *.* to mysqltest_1@localhost identified by "password"; -grant select, update, insert on test.* to mysqltest@localhost; +grant select, update, insert on test.* to mysqltest_1@localhost; commit; show grants for mysqltest_1@localhost; drop user mysqltest_1@localhost; @@ -351,6 +355,11 @@ DROP DATABASE testdb8; DROP DATABASE testdb9; DROP DATABASE testdb10; +# +# just SHOW PRIVILEGES test +# +SHOW PRIVILEGES; + # # Alter mysql system tables back to myisam # From 24ad655ab5469b4fa7f9b5ee2bcd69ca6fb47f70 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 26 Nov 2004 17:27:47 +0200 Subject: [PATCH 22/38] portability fix (some printf lack of NULL support in strings) --- sql/item.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sql/item.cc b/sql/item.cc index d1ebdb1822f..001fbef9505 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -112,7 +112,8 @@ void Item::cleanup() { DBUG_ENTER("Item::cleanup"); DBUG_PRINT("info", ("Item: 0x%lx, Type: %d, name %s, original name %s", - this, (int)type(), name, orig_name)); + this, (int)type(), name ? name : "(null)", + orig_name ? orig_name : "null")); fixed=0; marker= 0; if (orig_name) From 368cde22ac949bf4380cb012af59149a6dded2d1 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Nov 2004 12:35:21 +0100 Subject: [PATCH 23/38] better overflow checks in decimal2ulonglong better truncation check in decimal2ulonglong --- strings/decimal.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/strings/decimal.c b/strings/decimal.c index b8e8fd3725f..9b418dbe550 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -503,7 +503,7 @@ int decimal2ulonglong(decimal *from, ulonglong *to) { dec1 *buf=from->buf; ulonglong x=0; - int intg; + int intg, frac; if (from->sign) { @@ -515,14 +515,17 @@ int decimal2ulonglong(decimal *from, ulonglong *to) { ulonglong y=x; x=x*DIG_BASE + *buf++; - if (unlikely(x < y)) + if (unlikely(y > (ULONGLONG_MAX/DIG_BASE) || x < y)) { *to=y; return E_DEC_OVERFLOW; } } *to=x; - return from->frac ? E_DEC_TRUNCATED : E_DEC_OK; + for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1) + if (*buf++) + return E_DEC_TRUNCATED; + return E_DEC_OK; } int decimal2longlong(decimal *from, longlong *to) @@ -1928,6 +1931,7 @@ main() test_d2ull("18446744073709551616"); test_d2ull("-1"); test_d2ull("1.23"); + test_d2ull("9999999999999999999999999.000"); printf("==== longlong2decimal ====\n"); test_ll2d(LL(-12345)); From 4a9e7d384ee39ddd9f614688833ad832a100f8e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Nov 2004 13:39:15 +0100 Subject: [PATCH 24/38] mysql_priv.h: Reverts incomplete change of insert_fields() sql/mysql_priv.h: Reverts incomplete change of insert_fields() --- sql/mysql_priv.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index eb53394b96b..b7518c2c96d 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -809,8 +809,7 @@ bool get_key_map_from_key_list(key_map *map, TABLE *table, bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator *it, bool any_privileges, - bool allocate_view_names, - bool select_insert); + bool allocate_view_names); bool setup_tables(THD *thd, TABLE_LIST *tables, Item **conds, TABLE_LIST **leaves, bool refresh_only, bool select_insert); From df1f7cab7076d1299a61a53e366dc5b86eb85437 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Nov 2004 13:54:51 +0100 Subject: [PATCH 25/38] fix decimal2longlong too mysql-test/r/rpl_start_stop_slave.result: results updated --- mysql-test/r/rpl_start_stop_slave.result | 4 ++-- strings/decimal.c | 11 +++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/rpl_start_stop_slave.result b/mysql-test/r/rpl_start_stop_slave.result index 1b4d87124d1..1fcb586d1fb 100644 --- a/mysql-test/r/rpl_start_stop_slave.result +++ b/mysql-test/r/rpl_start_stop_slave.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(n int); start slave; diff --git a/strings/decimal.c b/strings/decimal.c index 9b418dbe550..6e607aaa173 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -532,7 +532,7 @@ int decimal2longlong(decimal *from, longlong *to) { dec1 *buf=from->buf; longlong x=0; - int intg; + int intg, frac; for (intg=from->intg; intg > 0; intg-=DIG_PER_DEC1) { @@ -540,11 +540,11 @@ int decimal2longlong(decimal *from, longlong *to) /* Attention: trick! we're calculating -|from| instead of |from| here - because |MIN_LONGLONG| > MAX_LONGLONG + because |LONGLONG_MIN| > LONGLONG_MAX so we can convert -9223372036854775808 correctly */ x=x*DIG_BASE - *buf++; - if (unlikely(x > y)) + if (unlikely(y < (LONGLONG_MAX/DIG_BASE) || x > y)) { *to= from->sign ? y : -y; return E_DEC_OVERFLOW; @@ -558,7 +558,10 @@ int decimal2longlong(decimal *from, longlong *to) } *to=from->sign ? x : -x; - return from->frac ? E_DEC_TRUNCATED : E_DEC_OK; + for (frac=from->frac; unlikely(frac > 0); frac-=DIG_PER_DEC1) + if (*buf++) + return E_DEC_TRUNCATED; + return E_DEC_OK; } /* From d777a9aa6ab2b85beaab43ab5e10e07f2056fc90 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Nov 2004 19:26:46 +0000 Subject: [PATCH 26/38] Change sql_mode BROKEN_NOT to HIGH_NOT_PRECEDENCE --- mysql-test/r/ansi.result | 2 +- mysql-test/r/bool.result | 2 +- mysql-test/r/sql_mode.result | 2 +- mysql-test/t/bool.test | 2 +- sql/mysql_priv.h | 2 +- sql/mysqld.cc | 2 +- sql/set_var.cc | 4 ++-- sql/sql_lex.cc | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/ansi.result b/mysql-test/r/ansi.result index 56676abba33..c515ee9a1e8 100644 --- a/mysql-test/r/ansi.result +++ b/mysql-test/r/ansi.result @@ -2,7 +2,7 @@ drop table if exists t1; set sql_mode="MySQL40"; select @@sql_mode; @@sql_mode -NO_FIELD_OPTIONS,MYSQL40,BROKEN_NOT +NO_FIELD_OPTIONS,MYSQL40,HIGH_NOT_PRECEDENCE set @@sql_mode="ANSI"; select @@sql_mode; @@sql_mode diff --git a/mysql-test/r/bool.result b/mysql-test/r/bool.result index 1ef4b55fc36..184046a2d6f 100644 --- a/mysql-test/r/bool.result +++ b/mysql-test/r/bool.result @@ -33,7 +33,7 @@ a SELECT * FROM t1 where (1 AND a) IS NULL; a NULL -set sql_mode='broken_not'; +set sql_mode='high_not_precedence'; select * from t1 where not a between 2 and 3; a set sql_mode=default; diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result index c25ae99b530..fea99086303 100644 --- a/mysql-test/r/sql_mode.result +++ b/mysql-test/r/sql_mode.result @@ -61,7 +61,7 @@ t1 CREATE TABLE `t1` ( set @@sql_mode="no_field_options,mysql323,mysql40"; show variables like 'sql_mode'; Variable_name Value -sql_mode NO_FIELD_OPTIONS,MYSQL323,MYSQL40,BROKEN_NOT +sql_mode NO_FIELD_OPTIONS,MYSQL323,MYSQL40,HIGH_NOT_PRECEDENCE show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/t/bool.test b/mysql-test/t/bool.test index 644fdbfbf60..53230dd5fa3 100644 --- a/mysql-test/t/bool.test +++ b/mysql-test/t/bool.test @@ -21,7 +21,7 @@ SELECT * FROM t1 where (1 AND a)=1; SELECT * FROM t1 where (1 AND a) IS NULL; # WL#638 - Behaviour of NOT does not follow SQL specification -set sql_mode='broken_not'; +set sql_mode='high_not_precedence'; select * from t1 where not a between 2 and 3; set sql_mode=default; select * from t1 where not a between 2 and 3; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b7518c2c96d..babb0c1aa6f 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -282,7 +282,7 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; #define MODE_ERROR_FOR_DIVISION_BY_ZERO (MODE_INVALID_DATES*2) #define MODE_TRADITIONAL (MODE_ERROR_FOR_DIVISION_BY_ZERO*2) #define MODE_NO_AUTO_CREATE_USER (MODE_TRADITIONAL*2) -#define MODE_BROKEN_NOT (MODE_NO_AUTO_CREATE_USER*2) +#define MODE_HIGH_NOT_PRECEDENCE (MODE_NO_AUTO_CREATE_USER*2) #define RAID_BLOCK_SIZE 1024 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 48b60cc6824..5a97daa04ae 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -221,7 +221,7 @@ const char *sql_mode_names[] = "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI", "NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES", "STRICT_ALL_TABLES", "NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES", "ERROR_FOR_DIVISION_BY_ZERO", - "TRADITIONAL", "NO_AUTO_CREATE_USER", "BROKEN_NOT", + "TRADITIONAL", "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE", NullS }; TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"", diff --git a/sql/set_var.cc b/sql/set_var.cc index 46865de9314..532547c2618 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -3146,9 +3146,9 @@ ulong fix_sql_mode(ulong sql_mode) MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER); if (sql_mode & MODE_MYSQL40) - sql_mode|= MODE_NO_FIELD_OPTIONS | MODE_BROKEN_NOT; + sql_mode|= MODE_NO_FIELD_OPTIONS | MODE_HIGH_NOT_PRECEDENCE; if (sql_mode & MODE_MYSQL323) - sql_mode|= MODE_NO_FIELD_OPTIONS | MODE_BROKEN_NOT; + sql_mode|= MODE_NO_FIELD_OPTIONS | MODE_HIGH_NOT_PRECEDENCE; if (sql_mode & MODE_TRADITIONAL) sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES | MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 63741bcb176..ce37318ca01 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -201,7 +201,7 @@ static int find_keyword(LEX *lex, uint len, bool function) lex->yylval->symbol.length=len; if ((symbol->tok == NOT_SYM) && - (lex->thd->variables.sql_mode & MODE_BROKEN_NOT)) + (lex->thd->variables.sql_mode & MODE_HIGH_NOT_PRECEDENCE)) return NOT2_SYM; if ((symbol->tok == OR_OR_SYM) && !(lex->thd->variables.sql_mode & MODE_PIPES_AS_CONCAT)) From 257763a9a35ff4212f71ccf356859d115899f430 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 27 Nov 2004 23:07:30 +0100 Subject: [PATCH 27/38] create/drop/rename user cleanup dbug/user.r: help cralified include/mysqld_error.h: new error message added mysql-test/r/grant.result: results updated mysql-test/r/grant2.result: results updated mysql-test/t/grant.test: results updated mysql-test/t/grant2.test: results updated sql/share/czech/errmsg.txt: error message updated sql/share/danish/errmsg.txt: error message updated sql/share/dutch/errmsg.txt: error message updated sql/share/english/errmsg.txt: error message updated sql/share/estonian/errmsg.txt: error message updated sql/share/french/errmsg.txt: error message updated sql/sql_acl.cc: changed error reporting for create/drop/rename user to be consistent with drop table sql/share/german/errmsg.txt: error message updated sql/share/greek/errmsg.txt: error message updated sql/share/hungarian/errmsg.txt: error message updated sql/share/italian/errmsg.txt: error message updated sql/share/japanese/errmsg.txt: error message updated sql/share/korean/errmsg.txt: error message updated sql/share/norwegian-ny/errmsg.txt: error message updated sql/share/norwegian/errmsg.txt: error message updated sql/share/polish/errmsg.txt: error message updated sql/share/portuguese/errmsg.txt: error message updated sql/share/romanian/errmsg.txt: error message updated sql/share/russian/errmsg.txt: error message updated sql/share/serbian/errmsg.txt: error message updated sql/share/slovak/errmsg.txt: error message updated sql/share/spanish/errmsg.txt: error message updated sql/share/swedish/errmsg.txt: error message updated sql/share/ukrainian/errmsg.txt: error message updated --- dbug/user.r | 6 +- include/mysqld_error.h | 5 +- mysql-test/r/grant.result | 2 +- mysql-test/r/grant2.result | 12 ++-- mysql-test/t/grant.test | 2 +- mysql-test/t/grant2.test | 12 ++-- sql/share/czech/errmsg.txt | 3 +- sql/share/danish/errmsg.txt | 3 +- sql/share/dutch/errmsg.txt | 3 +- sql/share/english/errmsg.txt | 3 +- sql/share/estonian/errmsg.txt | 3 +- sql/share/french/errmsg.txt | 3 +- sql/share/german/errmsg.txt | 3 +- sql/share/greek/errmsg.txt | 3 +- sql/share/hungarian/errmsg.txt | 3 +- sql/share/italian/errmsg.txt | 3 +- sql/share/japanese/errmsg.txt | 3 +- sql/share/korean/errmsg.txt | 3 +- sql/share/norwegian-ny/errmsg.txt | 3 +- sql/share/norwegian/errmsg.txt | 3 +- sql/share/polish/errmsg.txt | 3 +- sql/share/portuguese/errmsg.txt | 3 +- sql/share/romanian/errmsg.txt | 3 +- sql/share/russian/errmsg.txt | 3 +- sql/share/serbian/errmsg.txt | 3 +- sql/share/slovak/errmsg.txt | 3 +- sql/share/spanish/errmsg.txt | 3 +- sql/share/swedish/errmsg.txt | 3 +- sql/share/ukrainian/errmsg.txt | 3 +- sql/sql_acl.cc | 94 +++++++++++-------------------- 30 files changed, 101 insertions(+), 101 deletions(-) diff --git a/dbug/user.r b/dbug/user.r index 84c5bca908c..f03f0675e0f 100644 --- a/dbug/user.r +++ b/dbug/user.r @@ -907,8 +907,10 @@ Double the colon, if you want it in the path .SP 1 EX: \fCa,C::\\tmp\\log\fR .LI A[,file] -Like 'a[,file]' but close and reopen file after each write. It helps to get -a complete log file in case of crashes. +Like 'a[,file]' but ensure that data are written after each write +(this typically implies flush or close/reopen). It helps to get +a complete log file in case of crashes. This mode is implied in +multi-threaded environment. .LI d[,keywords] Enable output from macros with specified keywords. A null list of keywords implies that all keywords are selected. diff --git a/include/mysqld_error.h b/include/mysqld_error.h index f5994e8e71d..99f126cc23d 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -284,7 +284,7 @@ #define ER_WARN_DATA_TRUNCATED 1265 #define ER_WARN_USING_OTHER_HANDLER 1266 #define ER_CANT_AGGREGATE_2COLLATIONS 1267 -#define ER_HANDLE_USER 1268 +#define ER_DROP_USER 1268 #define ER_REVOKE_GRANTS 1269 #define ER_CANT_AGGREGATE_3COLLATIONS 1270 #define ER_CANT_AGGREGATE_NCOLLATIONS 1271 @@ -412,4 +412,5 @@ #define ER_VIEW_MULTIUPDATE 1393 #define ER_VIEW_NO_INSERT_FIELD_LIST 1394 #define ER_VIEW_DELETE_MERGE_VIEW 1395 -#define ER_ERROR_MESSAGES 396 +#define ER_CANNOT_USER 1396 +#define ER_ERROR_MESSAGES 397 diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 262afc3ce2f..31903a5dfd2 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -223,7 +223,7 @@ drop_user3@localhost, drop_user4@localhost; ERROR HY000: Can't revoke all privileges, grant for one or more of the requested users drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; -ERROR HY000: Operation DROP USER failed for 4 of the requested users +ERROR HY000: Operation DROP USER failed for 'drop_user1'@'localhost','drop_user2'@'localhost','drop_user3'@'localhost','drop_user4'@'localhost' drop table t1; grant usage on *.* to mysqltest_1@localhost identified by "password"; grant select, update, insert on test.* to mysqltest_1@localhost; diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index f2782f6f605..edfd1a07680 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -66,7 +66,7 @@ create table t1(c1 int); create table t2(c1 int, c2 int); create user 'mysqltest_1'; create user 'mysqltest_1'; -ERROR HY000: Operation CREATE USER failed for 1 of the requested users +ERROR HY000: Operation CREATE USER failed for 'mysqltest_1'@'%' create user 'mysqltest_2' identified by 'Mysqltest-2'; create user 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; grant select on *.* to 'mysqltest_2'; @@ -139,7 +139,7 @@ drop user 'mysqltest_1', 'mysqltest_3'; grant all on test.t1 to 'mysqltest_1'; ERROR 42000: 'root'@'localhost' is not allowed to create new users drop user 'mysqltest_1'; -ERROR HY000: Operation DROP USER failed for 1 of the requested users +ERROR HY000: Operation DROP USER failed for 'mysqltest_1'@'%' drop table t1, t2; insert into mysql.db set user='mysqltest_1', db='%', host='%'; flush privileges; @@ -169,16 +169,16 @@ drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; create user 'mysqltest_1', 'mysqltest_2' identified by 'Mysqltest-2', 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; rename user 'mysqltest_1' to 'mysqltest_1a', 'mysqltest_2' TO 'mysqltest_2a', 'mysqltest_3' TO 'mysqltest_3a'; drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; -ERROR HY000: Operation DROP USER failed for 3 of the requested users +ERROR HY000: Operation DROP USER failed for 'mysqltest_1'@'%','mysqltest_2'@'%','mysqltest_3'@'%' drop user 'mysqltest_1a', 'mysqltest_2a', 'mysqltest_3a'; create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; create user 'mysqltest_1a', 'mysqltest_2', 'mysqltest_3a'; -ERROR HY000: Operation CREATE USER failed for 1 of the requested users +ERROR HY000: Operation CREATE USER failed for 'mysqltest_2'@'%' rename user 'mysqltest_1a' to 'mysqltest_1b', 'mysqltest_2a' TO 'mysqltest_2b', 'mysqltest_3a' TO 'mysqltest_3b'; -ERROR HY000: Operation RENAME USER failed for 1 of the requested users +ERROR HY000: Operation RENAME USER failed for 'mysqltest_2a'@'%' drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; drop user 'mysqltest_1b', 'mysqltest_2b', 'mysqltest_3b'; -ERROR HY000: Operation DROP USER failed for 1 of the requested users +ERROR HY000: Operation DROP USER failed for 'mysqltest_2b'@'%' create user 'mysqltest_2' identified by 'Mysqltest-2'; drop user 'mysqltest_2' identified by 'Mysqltest-2'; 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 'identified by 'Mysqltest-2'' at line 1 diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index c004699d901..eda08ac0cdb 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -168,7 +168,7 @@ drop_user4@localhost; --error 1269 revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; ---error 1268 +--error 1396 drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop_user4@localhost; drop table t1; diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index 70cec9e0e35..69c42ce2252 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -91,7 +91,7 @@ create table t2(c1 int, c2 int); # # Three forms of CREATE USER create user 'mysqltest_1'; ---error 1268 +--error 1396 create user 'mysqltest_1'; create user 'mysqltest_2' identified by 'Mysqltest-2'; create user 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; @@ -127,7 +127,7 @@ drop user 'mysqltest_1', 'mysqltest_3'; # Grant must not create user --error 1211 grant all on test.t1 to 'mysqltest_1'; ---error 1268 +--error 1396 drop user 'mysqltest_1'; # # Cleanup @@ -164,18 +164,18 @@ create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; create user 'mysqltest_1', 'mysqltest_2' identified by 'Mysqltest-2', 'mysqltest_3' identified by password 'fffffffffffffffffffffffffffffffffffffffff'; rename user 'mysqltest_1' to 'mysqltest_1a', 'mysqltest_2' TO 'mysqltest_2a', 'mysqltest_3' TO 'mysqltest_3a'; ---error 1268 +--error 1396 drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; drop user 'mysqltest_1a', 'mysqltest_2a', 'mysqltest_3a'; # # Let one of multiple users fail create user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; ---error 1268 +--error 1396 create user 'mysqltest_1a', 'mysqltest_2', 'mysqltest_3a'; ---error 1268 +--error 1396 rename user 'mysqltest_1a' to 'mysqltest_1b', 'mysqltest_2a' TO 'mysqltest_2b', 'mysqltest_3a' TO 'mysqltest_3b'; drop user 'mysqltest_1', 'mysqltest_2', 'mysqltest_3'; ---error 1268 +--error 1396 drop user 'mysqltest_1b', 'mysqltest_2b', 'mysqltest_3b'; # # Obsolete syntax has been dropped diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 54d22e62dba..e8ea55f0739 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -296,7 +296,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -424,3 +424,4 @@ character-set=latin2 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 7385be9545c..3664e5ba0ef 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -287,7 +287,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -415,3 +415,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 7015ed90789..cd71ddc3588 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -296,7 +296,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -424,3 +424,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 54ca033657e..3050f94936f 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -284,7 +284,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -412,3 +412,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for %.256s", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index b89ebb42500..58b032ceb14 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -289,7 +289,7 @@ character-set=latin7 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -417,3 +417,4 @@ character-set=latin7 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 4e370a63099..a93a52606a9 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -284,7 +284,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -412,3 +412,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index b4afa45ee46..e657f9cb16a 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -297,7 +297,7 @@ character-set=latin1 "Daten abgeschnitten für Spalte '%s' in Zeile %ld", "Für Tabelle '%s' wird Speicher-Engine %s benutzt", "Unerlaubte Vermischung der Kollationen (%s,%s) und (%s,%s) für die Operation '%s'", -"Das Kommando %s scheiterte für %d von den betroffenen Benutzern", +"Kann einen oder mehrere der angegebenen Benutzer nicht löschen", "Kann nicht alle Berechtigungen widerrufen, grant for one or more of the requested users", "Unerlaubte Vermischung der Kollationen (%s,%s), (%s,%s), (%s,%s) für die Operation '%s'", "Unerlaubte Vermischung der Kollationen für die Operation '%s'", @@ -425,3 +425,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Das Kommando %s scheiterte für %.256s", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index afc91d0c69e..0bfcf513001 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -284,7 +284,7 @@ character-set=greek "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -412,3 +412,4 @@ character-set=greek "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 61c112170b2..51338770817 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -289,7 +289,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -417,3 +417,4 @@ character-set=latin2 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index e6a00332093..f7f553c0eca 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -284,7 +284,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -412,3 +412,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 98282af52d6..694447caa48 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -288,7 +288,7 @@ character-set=ujis "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -416,3 +416,4 @@ character-set=ujis "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index b10a83beee9..3916b10666d 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -284,7 +284,7 @@ character-set=euckr "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -412,3 +412,4 @@ character-set=euckr "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index e5a41b7d3d9..8165dc142fe 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -286,7 +286,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -414,3 +414,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 334313c1916..477c527968a 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -286,7 +286,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -414,3 +414,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 0d8deb30e77..5c56730068d 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -289,7 +289,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -417,3 +417,4 @@ character-set=latin2 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index e47a69a5c25..2ccde22a78f 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -286,7 +286,7 @@ character-set=latin1 "Dado truncado para coluna '%s' na linha %ld", "Usando engine de armazenamento %s para tabela '%s'", "Combinação ilegal de collations (%s,%s) e (%s,%s) para operação '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Não pode revocar todos os privilégios, grant para um ou mais dos usuários pedidos", "Ilegal combinação de collations (%s,%s), (%s,%s), (%s,%s) para operação '%s'", "Ilegal combinação de collations para operação '%s'", @@ -414,3 +414,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index c5a63223c22..2b2f6aa45a8 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -289,7 +289,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -417,3 +417,4 @@ character-set=latin2 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 04c51d5f532..58301983b25 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -289,7 +289,7 @@ character-set=koi8r "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -417,3 +417,4 @@ character-set=koi8r "îÅÌØÚÑ ÉÚÍÅÎÉÔØ ÂÏÌØÛÅ ÞÅÍ ÏÄÎÕ ÂÁÚÏ×ÕÀ ÔÁÂÌÉÃÕ ÉÓÐÏÌØÚÕÑ ÍÎÏÇÏÔÁÂÌÉÞÎÙÊ VIEW '%-.64s.%-.64s'" "îÅÌØÚÑ ×ÓÔÁ×ÌÑÔØ ÚÁÐÉÓÉ × ÍÎÏÇÏÔÁÂÌÉÞÎÙÊ VIEW '%-.64s.%-.64s' ÂÅÚ ÓÐÉÓËÁ ÐÏÌÅÊ" "îÅÌØÚÑ ÕÄÁÌÑÔØ ÉÚ ÍÎÏÇÏÔÁÂÌÉÞÎÏÇÏ VIEW '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index f267faeccbd..a245da6b677 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -277,7 +277,7 @@ character-set=cp1250 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -405,3 +405,4 @@ character-set=cp1250 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 8b7bb730cf0..69eddcfa9f6 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -292,7 +292,7 @@ character-set=latin2 "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -420,3 +420,4 @@ character-set=latin2 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index c0e663d6484..0eefed18088 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -288,7 +288,7 @@ character-set=latin1 "Datos truncados para columna '%s' en la línea %ld", "Usando motor de almacenamiento %s para tabla '%s'", "Ilegal mezcla de collations (%s,%s) y (%s,%s) para operación '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "No puede revocar todos los privilegios, derecho para uno o mas de los usuarios solicitados", "Ilegal mezcla de collations (%s,%s), (%s,%s), (%s,%s) para operación '%s'", "Ilegal mezcla de collations para operación '%s'", @@ -416,3 +416,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 831ccfbe978..be42d3889d0 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -284,7 +284,7 @@ character-set=latin1 "Data truncated for column '%s' at row %ld", "Använder handler %s för tabell '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -412,3 +412,4 @@ character-set=latin1 "Can not modify more than one base table through a join view '%-.64s.%-.64s'" "Can not insert into join view '%-.64s.%-.64s' without fields list" "Can not delete from join view '%-.64s.%-.64s'" +"Operation %s failed for '%.256s'", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 46a0adf922f..6d4c37803c7 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -290,7 +290,7 @@ character-set=koi8u "Data truncated for column '%s' at row %ld", "Using storage engine %s for table '%s'", "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", -"Operation %s failed for %d of the requested users", +"Cannot drop one or more of the requested users", "Can't revoke all privileges, grant for one or more of the requested users", "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", "Illegal mix of collations for operation '%s'", @@ -418,3 +418,4 @@ character-set=koi8u "îÅÍÏÖÌÉ×Ï ÏÎÏ×ÉÔÉ Â¦ÌØÛ ÎÉÖ ÏÄÎÕ ÂÁÚÏ×Õ ÔÁÂÌÉÃÀ ×ÙËÏÒÉÓÔÏ×ÕÀÞÉ VIEW '%-.64s.%-.64s', ÝÏ Í¦ÓÔ¦ÔØ ÄÅË¦ÌØËÁ ÔÁÂÌÉÃØ" "îÅÍÏÖÌÉ×Ï ÕÓÔÁ×ÉÔÉ ÒÑÄËÉ Õ VIEW '%-.64s.%-.64s', ÝÏ Í¦ÓÔÉÔØ ÄÅË¦ÌØËÁ ÔÁÂÌÉÃØ, ÂÅÚ ÓÐÉÓËÕ ÓÔÏ×Âæ×" "îÅÍÏÖÌÉ×Ï ×ÉÄÁÌÉÔÉ ÒÑÄËÉ Õ VIEW '%-.64s.%-.64s', ÝÏ Í¦ÓÔÉÔØ ÄÅË¦ÌØËÁ ÔÁÂÌÉÃØ" +"Operation %s failed for '%.256s'", diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d3bfb5b4d1d..0c6b061aa0c 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3770,7 +3770,7 @@ static int handle_grant_table(TABLE_LIST *tables, uint table_no, bool drop, const char *user; DBUG_ENTER("handle_grant_table"); - if (! table_no) + if (! table_no) // mysql.user table { /* The 'user' table has an unique index on (host, user). @@ -4119,6 +4119,16 @@ static int handle_grant_data(TABLE_LIST *tables, bool drop, DBUG_RETURN(result); } +static void append_user(String *str, LEX_USER *user) +{ + if (str->length()) + str->append(','); + str->append('\''); + str->append(user->user.str); + str->append("'@'"); + str->append(user->host.str); + str->append('\''); +} /* Create a list of users. @@ -4137,7 +4147,7 @@ bool mysql_create_user(THD *thd, List &list) { int result; int found; - uint failures; + String wrong_users; ulong sql_mode; LEX_USER *user_name; List_iterator user_list(list); @@ -4151,7 +4161,6 @@ bool mysql_create_user(THD *thd, List &list) rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); - failures= 0; while ((user_name= user_list++)) { /* @@ -4160,20 +4169,16 @@ bool mysql_create_user(THD *thd, List &list) */ if ((found= handle_grant_data(tables, 0, user_name, NULL))) { - if (found > 0) - sql_print_error("CREATE USER: Cannot create user: '%s'@'%s': " - "User exists", - user_name->user.str, - user_name->host.str); - failures++; + append_user(&wrong_users, user_name); result= TRUE; + continue; } sql_mode= thd->variables.sql_mode; thd->variables.sql_mode&= ~MODE_NO_AUTO_CREATE_USER; if (replace_user_table(thd, tables[0].table, *user_name, 0, 0, 1)) { - failures++; + append_user(&wrong_users, user_name); result= TRUE; } thd->variables.sql_mode= sql_mode; @@ -4183,7 +4188,7 @@ bool mysql_create_user(THD *thd, List &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) - my_error(ER_HANDLE_USER, MYF(0), "CREATE USER" , failures ); + my_error(ER_CANNOT_USER, MYF(0), "CREATE USER", wrong_users.c_ptr()); DBUG_RETURN(result); } @@ -4205,34 +4210,24 @@ bool mysql_drop_user(THD *thd, List &list) { int result; int found; - uint failures; + String wrong_users; LEX_USER *user_name; List_iterator user_list(list); TABLE_LIST tables[4]; DBUG_ENTER("mysql_drop_user"); - /* CREATE USER may be skipped on replication client. */ + /* DROP USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) DBUG_RETURN(result != 1); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); - failures= 0; while ((user_name= user_list++)) { - if ((found= handle_grant_data(tables, 1, user_name, NULL)) < 0) + if ((found= handle_grant_data(tables, 1, user_name, NULL)) <= 0) { - failures++; - result= TRUE; - } - else if (! found) - { - sql_print_error("DROP USER: Cannot drop user '%s'@'%s': " - "No such user", - user_name->user.str, - user_name->host.str); - failures++; + append_user(&wrong_users, user_name); result= TRUE; } } @@ -4241,7 +4236,7 @@ bool mysql_drop_user(THD *thd, List &list) rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) - my_error(ER_HANDLE_USER, MYF(0), "DROP USER" , failures ); + my_error(ER_CANNOT_USER, MYF(0), "DROP USER", wrong_users.c_ptr()); DBUG_RETURN(result); } @@ -4263,63 +4258,42 @@ bool mysql_rename_user(THD *thd, List &list) { int result= 0; int found; - uint failures; + String wrong_users; LEX_USER *user_from; LEX_USER *user_to; List_iterator user_list(list); TABLE_LIST tables[4]; DBUG_ENTER("mysql_rename_user"); - /* CREATE USER may be skipped on replication client. */ + /* RENAME USER may be skipped on replication client. */ if ((result= open_grant_tables(thd, tables))) DBUG_RETURN(result != 1); rw_wrlock(&LOCK_grant); VOID(pthread_mutex_lock(&acl_cache->lock)); - failures= 0; while ((user_from= user_list++)) { user_to= user_list++; - DBUG_ASSERT((user_to)); /* Syntax enforces pairs of users. */ + DBUG_ASSERT(user_to); /* Syntax enforces pairs of users. */ /* Search all in-memory structures and grant tables for a mention of the new user name. */ - if ((found= handle_grant_data(tables, 0, user_to, NULL))) + if (handle_grant_data(tables, 0, user_to, NULL) || + handle_grant_data(tables, 0, user_from, user_to) <= 0) { - if (found > 0) - sql_print_error("RENAME USER: Cannot rename to: '%s'@'%s': User exists", - user_to->user.str, - user_to->host.str); - failures++; + append_user(&wrong_users, user_from); result= TRUE; } - else - { - if ((found= handle_grant_data(tables, 0, user_from, user_to)) < 0) - { - failures++; - result= TRUE; - } - else if (! found) - { - sql_print_error("RENAME USER: Cannot rename user: '%s'@'%s': " - "No such user", - user_from->user.str, - user_from->host.str); - failures++; - result= TRUE; - } - } } VOID(pthread_mutex_unlock(&acl_cache->lock)); rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) - my_error(ER_HANDLE_USER, MYF(0), "RENAME USER", failures); + my_error(ER_CANNOT_USER, MYF(0), "RENAME USER", wrong_users.c_ptr()); DBUG_RETURN(result); } @@ -4382,13 +4356,13 @@ bool mysql_revoke_all(THD *thd, List &list) for (counter= 0, revoked= 0 ; counter < acl_dbs.elements ; ) { const char *user,*host; - + acl_db=dynamic_element(&acl_dbs,counter,ACL_DB*); if (!(user=acl_db->user)) user= ""; if (!(host=acl_db->host.hostname)) host= ""; - + if (!strcmp(lex_user->user.str,user) && !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { @@ -4419,7 +4393,7 @@ bool mysql_revoke_all(THD *thd, List &list) user= ""; if (!(host=grant_table->host)) host= ""; - + if (!strcmp(lex_user->user.str,user) && !my_strcasecmp(system_charset_info, lex_user->host.str, host)) { @@ -4454,14 +4428,14 @@ bool mysql_revoke_all(THD *thd, List &list) } } while (revoked); } - + VOID(pthread_mutex_unlock(&acl_cache->lock)); rw_unlock(&LOCK_grant); close_thread_tables(thd); - + if (result) my_message(ER_REVOKE_GRANTS, ER(ER_REVOKE_GRANTS), MYF(0)); - + DBUG_RETURN(result); } From 8f60d95ce34ba15c72bfbf4b1a46e0c7ac17a378 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 15:45:12 +0100 Subject: [PATCH 28/38] configure.in: A work-around for SCO, disable use of clock_gettime configure.in: A work-around for SCO, disable use of clock_gettime --- configure.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 1fcba6b8f5f..0d6e797f571 100644 --- a/configure.in +++ b/configure.in @@ -1931,9 +1931,11 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bzero chsize cuserid fchmod fcntl \ # # case "$target" in - *-*-aix4*) + *-*-aix4* | *-*-sco*) # (grr) aix 4.3 has a stub for clock_gettime, (returning ENOSYS) # and using AC_TRY_RUN is hard when cross-compiling + # We also disable for SCO for the time being, the headers for the + # thread library we use conflicts with other headers. ;; *) AC_CHECK_FUNCS(clock_gettime) ;; From 30db8445c10b0ae44077f1b2739a3bb07b4735a4 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 15:53:17 +0100 Subject: [PATCH 29/38] protection: TRASH in delete fixed a bug that it discovered include/my_sys.h: move TRASH to my_sys.h from sql_list.h sql/field.h: use TRASH macro sql/item.h: TRASH in delete sql/item_func.h: never delete item's manually! sql/opt_range.cc: TRASH in delete sql/sql_lex.h: TRASH in delete sql/sql_list.h: move TRASH to my_sys.h from sql_list.h sql/sql_parse.cc: don't use properties of deleted objects (even when it's safe) sql/sql_select.cc: TRASH in delete sql/sql_show.cc: TRASH in delete sql/sql_string.h: TRASH in delete --- include/my_sys.h | 2 ++ sql/field.h | 6 +----- sql/item.h | 5 +++-- sql/item_func.h | 6 +----- sql/opt_range.cc | 2 +- sql/sql_lex.h | 8 +++++--- sql/sql_list.h | 6 ------ sql/sql_parse.cc | 6 +++++- sql/sql_select.cc | 8 ++++++-- sql/sql_show.cc | 8 ++++++-- sql/sql_string.h | 4 ++-- 11 files changed, 32 insertions(+), 29 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 6a20f6aa9dd..3de3ec9687c 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -138,6 +138,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define my_memdup(A,B,C) _my_memdup((A),(B), __FILE__,__LINE__,C) #define my_strdup(A,C) _my_strdup((A), __FILE__,__LINE__,C) #define my_strdup_with_length(A,B,C) _my_strdup_with_length((A),(B),__FILE__,__LINE__,C) +#define TRASH(A,B) bfill(A, B, 0x8F) #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; @@ -164,6 +165,7 @@ extern char *my_strdup_with_length(const byte *from, uint length, #define CALLER_INFO_PROTO /* nothing */ #define CALLER_INFO /* nothing */ #define ORIG_CALLER_INFO /* nothing */ +#define TRASH(A,B) /* nothing */ #endif #ifdef HAVE_ALLOCA diff --git a/sql/field.h b/sql/field.h index 50ea1450085..d1c2fa3b6fd 100644 --- a/sql/field.h +++ b/sql/field.h @@ -37,11 +37,7 @@ class Field void operator=(Field &); public: static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } - static void operator delete(void *ptr_arg, size_t size) { -#ifdef SAFEMALLOC - bfill(ptr_arg, size, 0x8F); -#endif - } + static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); } char *ptr; // Position to field in record uchar *null_ptr; // Byte where null_bit is diff --git a/sql/item.h b/sql/item.h index 8f6d6581884..2c2978e841c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -120,8 +120,9 @@ public: static void *operator new(size_t size) {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) {} - static void operator delete(void *ptr,size_t size, MEM_ROOT *mem_root) {} + static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } + static void operator delete(void *ptr,size_t size, MEM_ROOT *mem_root) + { TRASH(ptr, size); } enum Type {FIELD_ITEM, FUNC_ITEM, SUM_FUNC_ITEM, STRING_ITEM, INT_ITEM, REAL_ITEM, NULL_ITEM, VARBIN_ITEM, diff --git a/sql/item_func.h b/sql/item_func.h index 03df78d721d..241240a49ca 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1035,11 +1035,7 @@ public: table->file->ft_handler=0; table->fulltext_searched=0; } - if (concat) - { - delete concat; - concat= 0; - } + concat= 0; DBUG_VOID_RETURN; } enum Functype functype() const { return FT_FUNC; } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 6392a2fee32..ab2eb4fdb72 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1360,7 +1360,7 @@ public: /* Table read plans are allocated on MEM_ROOT and are never deleted */ 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) {} + static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } }; class TRP_ROR_INTERSECT; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index fef78a363fe..e99e6138b6d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -283,8 +283,9 @@ public: } 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) {} - static void operator delete(void *ptr,size_t size, MEM_ROOT *mem_root) {} + static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); } + static void operator delete(void *ptr,size_t size, MEM_ROOT *mem_root) + { TRASH(ptr, size); } st_select_lex_node(): linkage(UNSPECIFIED_TYPE) {} virtual ~st_select_lex_node() {} inline st_select_lex_node* get_master() { return master; } @@ -820,7 +821,8 @@ struct st_lex_local: public st_lex { return (void*) alloc_root(mem_root, (uint) size); } - static void operator delete(void *ptr,size_t size) {} + static void operator delete(void *ptr,size_t size) + { TRASH(ptr, size); } }; void lex_init(void); diff --git a/sql/sql_list.h b/sql/sql_list.h index 141742c3d4a..657943f1e69 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -21,12 +21,6 @@ /* mysql standard class memory allocator */ -#ifdef SAFEMALLOC -#define TRASH(XX,YY) bfill((XX), (YY), 0x8F) -#else -#define TRASH(XX,YY) /* no-op */ -#endif - class Sql_alloc { public: diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 785d5a329ba..c04312f6ded 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1175,9 +1175,13 @@ end: void free_items(Item *item) { + Item *next; DBUG_ENTER("free_items"); - for (; item ; item=item->next) + for (; item ; item=next) + { + next=item->next; item->delete_self(); + } DBUG_VOID_RETURN; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d31305c5dd2..fb8e074ebf8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6025,9 +6025,13 @@ static void clear_tables(JOIN *join) class COND_CMP :public ilink { public: - static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } + static void *operator new(size_t size) + { + return (void*) sql_alloc((uint) size); + } static void operator delete(void *ptr __attribute__((unused)), - size_t size __attribute__((unused))) {} /*lint -e715 */ + size_t size __attribute__((unused))) + { TRASH(ptr, size); } Item *and_level; Item_func *cmp_func; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 19b5562cb8b..eb9ca43b56a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1257,9 +1257,13 @@ view_store_create_info(THD *thd, TABLE_LIST *table, String *buff) class thread_info :public ilink { public: - static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } + static void *operator new(size_t size) + { + return (void*) sql_alloc((uint) size); + } static void operator delete(void *ptr __attribute__((unused)), - size_t size __attribute__((unused))) {} /*lint -e715 */ + size_t size __attribute__((unused))) + { TRASH(ptr, size); } ulong thread_id; time_t start_time; diff --git a/sql/sql_string.h b/sql/sql_string.h index 2101db40f92..cb9db52c830 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -72,9 +72,9 @@ public: 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_arg,size_t size) - {} + { TRASH(ptr_arg, size); } static void operator delete(void *ptr_arg,size_t size, MEM_ROOT *mem_root) - {} + { TRASH(ptr_arg, size); } ~String() { free(); } inline void set_charset(CHARSET_INFO *charset) { str_charset= charset; } From 1a7783e0f6fd2bbb0cfe9705184d58dab389e606 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 16:31:14 +0100 Subject: [PATCH 30/38] skip last compress test if we're short of RAM --- mysql-test/r/func_compress.result | 4 ++-- mysql-test/t/func_compress.test | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index 11dbcca9431..9bc8e417e19 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -69,6 +69,6 @@ Error 1259 ZLIB: Input data corrupted Error 1256 Uncompressed data size too large; the maximum size is 1048576 (probably, length of uncompressed data was corrupted) drop table t1; set @@max_allowed_packet=1048576*100; -select compress(repeat('aaaaaaaaaa', 10000000)) is null; -compress(repeat('aaaaaaaaaa', 10000000)) is null +select compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null; +compress(repeat('aaaaaaaaaa', IF(XXX, 10, 10000000))) is null 0 diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index 7b70289d2c0..f46589e9e0e 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -38,7 +38,10 @@ drop table t1; # # Bug #5497: a problem with large strings +# note that when LOW_MEMORY is set the "test" below is meaningless # set @@max_allowed_packet=1048576*100; -select compress(repeat('aaaaaaaaaa', 10000000)) is null; +--replace_result "''" XXX "'1'" XXX +eval select compress(repeat('aaaaaaaaaa', IF('$LOW_MEMORY', 10, 10000000))) is null; + From d2c7736c59403d8df8029773c3ea70202b27946b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 16:58:05 +0100 Subject: [PATCH 31/38] fix for decimal.c strings/decimal.c: fix --- strings/decimal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/strings/decimal.c b/strings/decimal.c index 6e607aaa173..b88be6116a6 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -873,7 +873,7 @@ int decimal_round(decimal *from, decimal *to, int scale, decimal_round_mode mode error=E_DEC_TRUNCATED; } - if (scale+from->intg <0) + if (scale+from->intg <= 0) { decimal_make_zero(to); return E_DEC_OK; From 5607539c5b5dee4809e8e370527d3542387e27a4 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 17:06:40 +0100 Subject: [PATCH 32/38] bad merge fixed --- mysql-test/r/rpl_start_stop_slave.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/rpl_start_stop_slave.result b/mysql-test/r/rpl_start_stop_slave.result index 1b4d87124d1..1fcb586d1fb 100644 --- a/mysql-test/r/rpl_start_stop_slave.result +++ b/mysql-test/r/rpl_start_stop_slave.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(n int); start slave; From 63c3ab1e6cd763eb2829f6de037c1c7c62f8573e Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 17:30:52 +0100 Subject: [PATCH 33/38] limit Max_data_length in 'show table status' --- mysql-test/r/view.result | 4 ++-- mysql-test/t/view.test | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index e2c6b3f2ae2..4783085dec9 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -8,7 +8,7 @@ create temporary table t1 (a int, b int); create view v1 (c) as select b+1 from t1; ERROR HY000: View's SELECT contains a temporary table 't1' drop table t1; -create table t1 (a int, b int); +create table t1 (a int, b int) max_rows=1000000; insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10); create view v1 (c,d) as select a,b+@@global.max_user_connections from t1; ERROR HY000: View's SELECT contains a variable or parameter @@ -149,7 +149,7 @@ v5 VIEW v6 VIEW show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MyISAM 9 Fixed 5 9 45 38654705663 1024 0 NULL # # NULL latin1_swedish_ci NULL +t1 MyISAM 9 Fixed 5 9 45 150994943 1024 0 NULL # # NULL latin1_swedish_ci NULL max_rows=1000000 v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view v2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view v3 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL view diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 92747323336..1af95d8c370 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -19,7 +19,7 @@ create temporary table t1 (a int, b int); create view v1 (c) as select b+1 from t1; drop table t1; -create table t1 (a int, b int); +create table t1 (a int, b int) max_rows=1000000; insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10); #view with variable From 4c9c3f32de96fd9a35ee1a9337dab1da6f99fddb Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 18:00:42 +0100 Subject: [PATCH 34/38] view.test: more max_rows for show table status comment spellchecking... mysql-test/r/view.result: more max_rows for show table status mysql-test/t/view.test: more max_rows for show table status comment spellchecking... --- mysql-test/r/view.result | 8 ++---- mysql-test/t/view.test | 58 +++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 4783085dec9..f4430ae1004 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1213,18 +1213,14 @@ select * from v1; drop view v1; drop table t1; create function x1 () returns int return 5; -create table t1 (s1 int); +create table t1 (s1 int) max_rows=1000000; create view v1 as select x1() from t1; drop function x1; select * from v1; ERROR 42000: FUNCTION test.x1 does not exist show table status; Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL -v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL FUNCTION test.x1 does not exist -show table status; -Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment -t1 MyISAM 9 Fixed 0 0 0 21474836479 1024 0 NULL # # NULL latin1_swedish_ci NULL +t1 MyISAM 9 Fixed 0 0 0 83886079 1024 0 NULL # # NULL latin1_swedish_ci NULL max_rows=1000000 v1 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL # # NULL NULL NULL NULL FUNCTION test.x1 does not exist drop view v1; drop table t1; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 1af95d8c370..5b2eeaca966 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -9,12 +9,12 @@ use test; # some basic test of views and its functionality # -# create view on unexistence table +# create view on nonexistent table -- error 1146 create view v1 (c,d) as select a,b from t1; create temporary table t1 (a int, b int); -#view on temporary table +# view on temporary table -- error 1352 create view v1 (c) as select b+1 from t1; drop table t1; @@ -22,7 +22,7 @@ drop table t1; create table t1 (a int, b int) max_rows=1000000; insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10); -#view with variable +# view with variable -- error 1351 create view v1 (c,d) as select a,b+@@global.max_user_connections from t1; @@ -30,7 +30,7 @@ create view v1 (c,d) as select a,b+@@global.max_user_connections from t1; create view v1 (c) as select b+1 from t1; select c from v1; -#tamporary table should not shade (hide) table of view +# temporary table should not hide table of view create temporary table t1 (a int, b int); # this is empty select * from t1; @@ -42,7 +42,7 @@ show create view v1; show create view t1; drop table t1; -# try to use fields from underlaid table +# try to use fields from underlying table -- error 1054 select a from v1; -- error 1054 @@ -52,14 +52,14 @@ select b from v1; -- error 1054 select v1.b from v1; -# view with different algorithms (explain out put are differ) +# view with different algorithms (explain output differs) explain extended select c from v1; create algorithm=temptable view v2 (c) as select b+1 from t1; show create view v2; select c from v2; explain extended select c from v2; -# try to use underlaid table fields in VIEW creation process +# try to use underlying table fields in VIEW creation process -- error 1054 create view v3 (c) as select a+1 from v1; -- error 1054 @@ -127,19 +127,19 @@ show grants for test@localhost; revoke create view on test.* from test@localhost; show grants for test@localhost; -#try to drop unexisten VIEW +# try to drop nonexistent VIEW -- error 1051 drop view v100; -#try to drop table with DROP VIEW +# try to drop table with DROP VIEW -- error 1347 drop view t1; -#try to drop VIEW with DROP TABLE +# try to drop VIEW with DROP TABLE -- error 1051 drop table v1; -#try to drop table with DROP VIEW +# try to drop table with DROP VIEW drop view v1,v2; drop table t1; @@ -213,7 +213,7 @@ grant select (c) on mysqltest.v1 to mysqltest_1@localhost; connection user1; select c from mysqltest.v1; -# there are not privilege ob column 'd' +# there are no privileges on column 'd' -- error 1143 select d from mysqltest.v1; @@ -233,7 +233,7 @@ grant select (c) on mysqltest.v1 to mysqltest_1@localhost; connection user1; select c from mysqltest.v1; -# there are not privilege ob column 'd' +# there are no privileges on column 'd' -- error 1143 select d from mysqltest.v1; @@ -288,7 +288,7 @@ explain select c from mysqltest.v4; -- error 1142 show create view mysqltest.v4; -# allow to see one of underlaing table +# allow to see one of underlying table connection root; grant select on mysqltest.t1 to mysqltest_1@localhost; connection user1; @@ -328,7 +328,7 @@ delete from mysql.user where user='mysqltest_1'; drop database mysqltest; # -# QUERY CHECHE options for VIEWs +# QUERY CACHE options for VIEWs # set GLOBAL query_cache_size=1355776; flush status; @@ -425,7 +425,7 @@ drop table t1; drop view v1,v2; # -# LIMIT clasuse test +# LIMIT clause test # create table t1 (a int); insert into t1 values (1), (2), (3), (4); @@ -538,7 +538,7 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM mysqltest_1@localhost; drop database mysqltest; # -# MEREGE VIEW with WHERE clause +# MERGE VIEW with WHERE clause # create table t1 (a int, b int, primary key(b)); insert into t1 values (1,20), (2,30), (3,40), (4,50), (5,100); @@ -811,7 +811,7 @@ create view mysqltest.v1 as select * from mysqltest.t1; -- error 1143 create view v3 as select a from mysqltest.t2; -# give CRETEA VIEW privileges (without any privileges for result colemn) +# give CREATE VIEW privileges (without any privileges for result column) connection root; create table mysqltest.v3 (b int); grant create view on mysqltest.v3 to mysqltest_1@localhost; @@ -826,7 +826,7 @@ drop view mysqltest.v3; connection user1; create view mysqltest.v3 as select b from mysqltest.t2; -# give UPDATE and INSERT privilege (to get more privileges then anderlying +# give UPDATE and INSERT privilege (to get more privileges then underlying # table) connection root; grant create view, update, insert on mysqltest.v3 to mysqltest_1@localhost; @@ -836,8 +836,8 @@ connection user1; create view mysqltest.v3 as select b from mysqltest.t2; -# If give other privileges for VIEW then underlaying table have => -# creation prohibited +# If we would get more privileges on VIEW then we have on +# underlying tables => creation prohibited connection root; create table mysqltest.v3 (b int); grant select(b) on mysqltest.v3 to mysqltest_1@localhost; @@ -897,7 +897,7 @@ drop view v1; drop table `t1a``b`; # -# Changing of underlaying table +# Changing of underlying table # create table t1 (col1 char(5),col2 char(5)); create view v1 as select * from t1; @@ -927,7 +927,7 @@ call p1(); drop procedure p1; # -# updateablity should be transitive +# updatablity should be transitive # create table t1 (col1 int,col2 char(22)); insert into t1 values(5,'Hello, world of views'); @@ -960,7 +960,7 @@ drop view v1; drop table t1; # -# Test of view updatebility in prepared statement +# Test of view updatability in prepared statement # create table t1 (a int); create view v1 as select a from t1; @@ -1162,23 +1162,21 @@ drop view v1; drop table t1; # -# VIEW over droped function +# VIEW over dropped function # create function x1 () returns int return 5; -create table t1 (s1 int); +create table t1 (s1 int) max_rows=1000000; create view v1 as select x1() from t1; drop function x1; -- error 1305 select * from v1; --replace_column 12 # 13 # show table status; ---replace_column 12 # 13 # -show table status; drop view v1; drop table t1; # -# VIEW with floating point (long bumber) as column +# VIEW with floating point (long number) as column # create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1; show create view v1; @@ -1213,7 +1211,7 @@ select * from v1; drop view v1; # -# bug handlimg from VIEWs +# bug handling from VIEWs # create view v1 as select 'a',1; create view v2 as select * from v1 union all select * from v1; From 46e12a2b482fbd133920c780042463ed03c790b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 21:02:30 +0300 Subject: [PATCH 35/38] Fix for division by zero problem: * Don't try building ROR-intersect if the queried table has zero rows * Don't ever produce an estimate of zero returned rows. --- sql/opt_range.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ab2eb4fdb72..e92d266ba28 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -2716,7 +2716,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, double min_cost= read_time; DBUG_ENTER("get_best_ror_intersect"); - if (tree->n_ror_scans < 2) + if ((tree->n_ror_scans < 2) || !param->table->file->records) DBUG_RETURN(NULL); /* @@ -2803,6 +2803,9 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, min_cost= intersect->total_cost; best_rows= (ha_rows)(intersect->records_fract* rows2double(param->table->file->records)); + /* Prevent divisons by zero */ + if (!best_rows) + best_rows= 1; is_best_covering= intersect->is_covering; intersect_scans_best= intersect_scans_end; best_index_scan_costs= intersect->index_scan_costs; @@ -2847,6 +2850,9 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, min_cost= intersect->total_cost; best_rows= (ha_rows)(intersect->records_fract* rows2double(param->table->file->records)); + /* Prevent divisons by zero */ + if (!best_rows) + best_rows= 1; is_best_covering= intersect->is_covering; best_index_scan_costs= intersect->index_scan_costs; } @@ -2866,7 +2872,7 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree, trp->last_scan= trp->first_scan + best_num; trp->is_covering= is_best_covering; trp->read_cost= min_cost; - trp->records= best_rows? best_rows : 1; + trp->records= best_rows; trp->index_scan_costs= best_index_scan_costs; trp->cpk_scan= cpk_scan; DBUG_PRINT("info", From 1b898a22460a369b8ca21f573973a8a0518e85d4 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 19:48:41 +0100 Subject: [PATCH 36/38] post-merge fix --- mysql-test/r/select.result | 62 +++++++++++++------------------------- mysql-test/t/select.test | 2 -- 2 files changed, 21 insertions(+), 43 deletions(-) diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index 79af86777dc..a05b379ed88 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -2353,6 +2353,27 @@ select * from t2,t3 where t2.s = t3.s; s s two two drop table t1, t2, t3; +create table t1 (a integer, b integer, index(a), index(b)); +create table t2 (c integer, d integer, index(c), index(d)); +insert into t1 values (1,2), (2,2), (3,2), (4,2); +insert into t2 values (1,3), (2,3), (3,4), (4,4); +explain select * from t1 left join t2 on a=c where d in (4); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ALL a NULL NULL NULL 3 Using where +select * from t1 left join t2 on a=c where d in (4); +a b c d +3 2 3 4 +4 2 4 4 +explain select * from t1 left join t2 on a=c where d = 4; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref c,d d 5 const 2 Using where +1 SIMPLE t1 ALL a NULL NULL NULL 3 Using where +select * from t1 left join t2 on a=c where d = 4; +a b c d +3 2 3 4 +4 2 4 4 +drop table t1, t2; CREATE TABLE t1 ( i int(11) NOT NULL default '0', c char(10) NOT NULL default '', @@ -2365,45 +2386,4 @@ INSERT INTO t1 VALUES (3,'c'); EXPLAIN SELECT i FROM t1 WHERE i=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index -EXPLAIN SELECT i FROM t1 WHERE i=1; -id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index -DROP TABLE t1; -create table t1 (a integer, b integer, index(a), index(b)); -create table t2 (c integer, d integer, index(c), index(d)); -insert into t1 values (1,2), (2,2), (3,2), (4,2); -insert into t2 values (1,3), (2,3), (3,4), (4,4); -explain select * from t1 left join t2 on a=c where d in (4); -table type possible_keys key key_len ref rows Extra -t2 ref c,d d 5 const 2 Using where -t1 ALL a NULL NULL NULL 3 Using where -select * from t1 left join t2 on a=c where d in (4); -a b c d -3 2 3 4 -4 2 4 4 -explain select * from t1 left join t2 on a=c where d = 4; -table type possible_keys key key_len ref rows Extra -t2 ref c,d d 5 const 2 Using where -t1 ALL a NULL NULL NULL 3 Using where -select * from t1 left join t2 on a=c where d = 4; -a b c d -3 2 3 4 -4 2 4 4 -drop table t1, t2; -CREATE TABLE t1 ( -i int(11) NOT NULL default '0', -c char(10) NOT NULL default '', -PRIMARY KEY (i), -UNIQUE KEY c (c) -) TYPE=MyISAM; -INSERT INTO t1 VALUES (1,'a'); -INSERT INTO t1 VALUES (2,'b'); -INSERT INTO t1 VALUES (3,'c'); -EXPLAIN SELECT i FROM t1 WHERE i=1; -table type possible_keys key key_len ref rows Extra -t1 const PRIMARY PRIMARY 4 const 1 Using index -EXPLAIN SELECT i FROM t1 WHERE i=1; -table type possible_keys key key_len ref rows Extra -t1 const PRIMARY PRIMARY 4 const 1 Using index ->>>>>>> DROP TABLE t1; diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test index 84aab132503..9bbd26a9c1c 100644 --- a/mysql-test/t/select.test +++ b/mysql-test/t/select.test @@ -1929,6 +1929,4 @@ INSERT INTO t1 VALUES (3,'c'); EXPLAIN SELECT i FROM t1 WHERE i=1; -EXPLAIN SELECT i FROM t1 WHERE i=1; - DROP TABLE t1; From fe46667ad94434650ca21863077bca8deabc1b5f Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 28 Nov 2004 21:55:38 +0100 Subject: [PATCH 37/38] don't cast LEX_STRING to char* :) --- sql/item_func.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index 01866a786a6..eb3db156056 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3543,7 +3543,7 @@ Item_func_sp::execute(Item **itp) m_sp= sp_find_function(thd, m_name); if (! m_sp) { - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); DBUG_RETURN(-1); } @@ -3577,7 +3577,7 @@ Item_func_sp::field_type() const DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns)); DBUG_RETURN(m_sp->m_returns); } - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); DBUG_RETURN(MYSQL_TYPE_STRING); } @@ -3593,7 +3593,7 @@ Item_func_sp::result_type() const { DBUG_RETURN(m_sp->result()); } - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); DBUG_RETURN(STRING_RESULT); } @@ -3606,7 +3606,7 @@ Item_func_sp::fix_length_and_dec() m_sp= sp_find_function(current_thd, m_name); if (! m_sp) { - my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname); + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); } else { From d212891f6f0c0de275190f52672f3346979e07c0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 29 Nov 2004 09:00:39 +0100 Subject: [PATCH 38/38] ndb - scan bug fix + more test cases ndb/include/ndbapi/NdbScanOperation.hpp: Improved doc. a bit ndb/src/ndbapi/NdbConnectionScan.cpp: Set error code ndb/src/ndbapi/NdbScanOperation.cpp: Check error directly after taking mutex ndb/test/ndbapi/testScan.cpp: new scan test with lots of threads ndb/test/run-test/daily-basic-tests.txt: Added two more scan tests Collapsed testTransactions & testOperations --- ndb/include/ndbapi/NdbScanOperation.hpp | 11 +- ndb/src/ndbapi/NdbConnectionScan.cpp | 2 +- ndb/src/ndbapi/NdbScanOperation.cpp | 35 +- ndb/test/ndbapi/testScan.cpp | 130 ++++++- ndb/test/run-test/daily-basic-tests.txt | 496 +----------------------- 5 files changed, 172 insertions(+), 502 deletions(-) diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp index 2e4d173ac75..5689b62526c 100644 --- a/ndb/include/ndbapi/NdbScanOperation.hpp +++ b/ndb/include/ndbapi/NdbScanOperation.hpp @@ -127,14 +127,23 @@ protected: NdbReceiver** m_receivers; // All receivers Uint32* m_prepared_receivers; // These are to be sent - + + /** + * owned by API/user thread + */ Uint32 m_current_api_receiver; Uint32 m_api_receivers_count; NdbReceiver** m_api_receivers; // These are currently used by api + /** + * owned by receiver thread + */ Uint32 m_conf_receivers_count; // NOTE needs mutex to access NdbReceiver** m_conf_receivers; // receive thread puts them here + /** + * owned by receiver thread + */ Uint32 m_sent_receivers_count; // NOTE needs mutex to access NdbReceiver** m_sent_receivers; // receive thread puts them here diff --git a/ndb/src/ndbapi/NdbConnectionScan.cpp b/ndb/src/ndbapi/NdbConnectionScan.cpp index a1a220caacf..b0c546c512a 100644 --- a/ndb/src/ndbapi/NdbConnectionScan.cpp +++ b/ndb/src/ndbapi/NdbConnectionScan.cpp @@ -56,7 +56,7 @@ NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){ const ScanTabRef * ref = CAST_CONSTPTR(ScanTabRef, aSignal->getDataPtr()); if(checkState_TransId(&ref->transId1)){ - theScanningOp->theError.code = ref->errorCode; + theScanningOp->setErrorCode(ref->errorCode); theScanningOp->execCLOSE_SCAN_REP(); if(!ref->closeNeeded){ return 0; diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 282b831f8fd..6eb5167e385 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -277,9 +277,9 @@ NdbScanOperation::fix_receivers(Uint32 parallel){ void NdbScanOperation::receiver_delivered(NdbReceiver* tRec){ if(theError.code == 0){ - if(DEBUG_NEXT_RESULT) - ndbout_c("receiver_delivered"); - + if(DEBUG_NEXT_RESULT) + ndbout_c("receiver_delivered"); + Uint32 idx = tRec->m_list_index; Uint32 last = m_sent_receivers_count - 1; if(idx != last){ @@ -492,6 +492,9 @@ int NdbScanOperation::nextResult(bool fetchAllowed) Uint32 nodeId = theNdbCon->theDBnode; TransporterFacade* tp = TransporterFacade::instance(); Guard guard(tp->theMutexPtr); + if(theError.code) + return -1; + Uint32 seq = theNdbCon->theNodeSequence; if(seq == tp->getNodeSequence(nodeId) && send_next_scan(idx, false) == 0){ @@ -685,10 +688,8 @@ void NdbScanOperation::closeScan() void NdbScanOperation::execCLOSE_SCAN_REP(){ - m_api_receivers_count = 0; m_conf_receivers_count = 0; m_sent_receivers_count = 0; - m_current_api_receiver = m_ordered ? theParallelism : 0; } void NdbScanOperation::release() @@ -1333,6 +1334,8 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){ if(DEBUG_NEXT_RESULT) ndbout_c("performing fetch..."); TransporterFacade* tp = TransporterFacade::instance(); Guard guard(tp->theMutexPtr); + if(theError.code) + return -1; Uint32 seq = theNdbCon->theNodeSequence; Uint32 nodeId = theNdbCon->theDBnode; if(seq == tp->getNodeSequence(nodeId) && !send_next_scan_ordered(s_idx)){ @@ -1346,6 +1349,13 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){ continue; } if(DEBUG_NEXT_RESULT) ndbout_c("return -1"); + setErrorCode(4028); + return -1; + } + + if(theError.code){ + setErrorCode(theError.code); + if(DEBUG_NEXT_RESULT) ndbout_c("return -1"); return -1; } @@ -1355,11 +1365,9 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed){ memcpy(arr, m_conf_receivers, u_last * sizeof(char*)); if(DEBUG_NEXT_RESULT) ndbout_c("sent: %d recv: %d", tmp, u_last); - if(theError.code){ - setErrorCode(theError.code); - if(DEBUG_NEXT_RESULT) ndbout_c("return -1"); - return -1; - } + } else { + setErrorCode(4028); + return -1; } } else { if(DEBUG_NEXT_RESULT) ndbout_c("return 2"); @@ -1497,6 +1505,13 @@ NdbScanOperation::close_impl(TransporterFacade* tp){ } } + if(theError.code) + { + m_api_receivers_count = 0; + m_current_api_receiver = m_ordered ? theParallelism : 0; + } + + /** * move all conf'ed into api * so that send_next_scan can check if they needs to be closed diff --git a/ndb/test/ndbapi/testScan.cpp b/ndb/test/ndbapi/testScan.cpp index 51913e8fbf9..22ec3fff327 100644 --- a/ndb/test/ndbapi/testScan.cpp +++ b/ndb/test/ndbapi/testScan.cpp @@ -90,11 +90,59 @@ int runLoadAllTables(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +char orderedPkIdxName[255]; + +int createOrderedPkIndex(NDBT_Context* ctx, NDBT_Step* step){ + + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + + // Create index + BaseString::snprintf(orderedPkIdxName, sizeof(orderedPkIdxName), + "IDC_O_PK_%s", pTab->getName()); + NdbDictionary::Index pIdx(orderedPkIdxName); + pIdx.setTable(pTab->getName()); + pIdx.setType(NdbDictionary::Index::OrderedIndex); + pIdx.setLogging(false); + + for (int c = 0; c< pTab->getNoOfColumns(); c++){ + const NdbDictionary::Column * col = pTab->getColumn(c); + if(col->getPrimaryKey()){ + pIdx.addIndexColumn(col->getName()); + } + } + + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + ndbout << "FAILED! to create index" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + return NDBT_FAILED; + } + + return NDBT_OK; +} + +int createOrderedPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + + // Drop index + if (pNdb->getDictionary()->dropIndex(orderedPkIdxName, + pTab->getName()) != 0){ + ndbout << "FAILED! to drop index" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } + + return NDBT_OK; +} + + int runScanReadRandomTable(NDBT_Context* ctx, NDBT_Step* step){ int loops = ctx->getNumLoops(); int records = ctx->getNumRecords(); int parallelism = ctx->getProperty("Parallelism", 240); - int abort = ctx->getProperty("AbortProb"); + int abort = ctx->getProperty("AbortProb", 5); int i = 0; while (igetNumLoops(); int records = ctx->getNumRecords(); int parallelism = ctx->getProperty("Parallelism", 240); - int abort = ctx->getProperty("AbortProb"); + int abort = ctx->getProperty("AbortProb", 5); int i = 0; HugoTransactions hugoTrans(*ctx->getTab()); @@ -232,11 +280,58 @@ int runScanRead(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int runRandScanRead(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 240); + int abort = ctx->getProperty("AbortProb", 5); + + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (iisTestStopped()) { + g_info << i << ": "; + NdbOperation::LockMode lm = (NdbOperation::LockMode)(rand() % 3); + if (hugoTrans.scanReadRecords(GETNDB(step), + records, abort, parallelism, + lm) != 0){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + +int runScanReadIndex(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int parallelism = ctx->getProperty("Parallelism", 240); + int abort = ctx->getProperty("AbortProb", 5); + const NdbDictionary::Index * pIdx = + GETNDB(step)->getDictionary()->getIndex(orderedPkIdxName, + ctx->getTab()->getName()); + + int i = 0; + HugoTransactions hugoTrans(*ctx->getTab()); + while (pIdx && iisTestStopped()) { + g_info << i << ": "; + bool sort = (rand() % 100) > 50 ? true : false; + NdbOperation::LockMode lm = (NdbOperation::LockMode)(rand() % 3); + if (hugoTrans.scanReadRecords(GETNDB(step), pIdx, + records, abort, parallelism, + lm, + sort) != 0){ + return NDBT_FAILED; + } + i++; + } + return NDBT_OK; +} + int runScanReadCommitted(NDBT_Context* ctx, NDBT_Step* step){ int loops = ctx->getNumLoops(); int records = ctx->getNumRecords(); int parallelism = ctx->getProperty("Parallelism", 240); - int abort = ctx->getProperty("AbortProb"); + int abort = ctx->getProperty("AbortProb", 5); int i = 0; HugoTransactions hugoTrans(*ctx->getTab()); @@ -425,7 +520,7 @@ int runScanUpdate(NDBT_Context* ctx, NDBT_Step* step){ int loops = ctx->getNumLoops(); int records = ctx->getNumRecords(); int parallelism = ctx->getProperty("Parallelism", 1); - int abort = ctx->getProperty("AbortProb"); + int abort = ctx->getProperty("AbortProb", 5); int i = 0; HugoTransactions hugoTrans(*ctx->getTab()); while (igetNumLoops(); int records = ctx->getNumRecords(); int parallelism = ctx->getProperty("Parallelism", 240); - int abort = ctx->getProperty("AbortProb"); + int abort = ctx->getProperty("AbortProb", 5); int i = 0; HugoTransactions hugoTrans(*ctx->getTab()); while (i